Compare commits

...

1000 Commits

Author SHA1 Message Date
Mahmoud-Emad
d7e4e8ec56 refactor: Change timestamp types to i64
- Update `created_at` type from u32 to i64
- Update `updated_at` type from u32 to i64
2025-12-02 15:40:16 +02:00
46e0e56e61 ... 2025-12-02 10:17:45 +01:00
ce3bb5cd9e atlas back 2025-12-02 09:53:35 +01:00
c3690f3d53 ... 2025-12-02 08:45:38 +01:00
e3aaa1b0f8 ... 2025-12-02 07:53:20 +01:00
4096b52244 ... 2025-12-02 05:41:57 +01:00
da2429104a ... 2025-12-02 05:05:11 +01:00
00ac4c8bd1 ... 2025-12-02 05:00:44 +01:00
7db14632d6 ... 2025-12-02 04:53:48 +01:00
63e160029e ... 2025-12-02 04:42:01 +01:00
e55a9741e2 ... 2025-12-02 04:38:48 +01:00
75b548b439 ... 2025-12-02 04:34:43 +01:00
ad65392806 ... 2025-12-02 04:23:21 +01:00
8c8369c42b ... 2025-12-02 04:15:22 +01:00
29ab30788e ... 2025-12-02 03:27:17 +01:00
690af291b5 ... 2025-12-01 20:53:20 +01:00
88680f1954 ... 2025-12-01 19:53:51 +01:00
7dba940d80 ... 2025-12-01 19:35:18 +01:00
5d44d49861 ... 2025-12-01 19:02:06 +01:00
c22e9ae8ce ... 2025-12-01 19:00:31 +01:00
55966be158 ... 2025-12-01 16:45:47 +01:00
Mahmoud-Emad
5f9a95f2ca refactor: Improve site configuration and navigation handling
- Consolidate site configuration loading and parsing
- Refactor navbar and menu item processing logic
- Add console output for configuration steps
- Update copyright year dynamically
- Simplify and clarify parameter handling
- Enhance error handling for missing required parameters
2025-12-01 15:32:09 +02:00
Omdanii
efbe50bdea Merge pull request #221 from Incubaid/dev_docusaurus
Docusaurus Landing Page Slug Handling & Documentation Updates
2025-12-01 15:21:11 +02:00
Mahmoud-Emad
f447c7a3f1 Merge branch 'development' into dev_docusaurus 2025-12-01 15:16:17 +02:00
Omdanii
c346d0c5ed Merge pull request #219 from Incubaid/development_hetzner
feat: Improve Ubuntu installation and SSH execution
2025-12-01 13:03:24 +02:00
Mahmoud-Emad
ba46ed62ef refactor: Update documentation for HeroLib Docusaurus integration
- Refactor site.page_category and site.page arguments
- Update hero command usage for ebook paths
- Clarify Atlas and Doctree integration
- Add new ebook structure examples
- Update HeroScript actions reference
2025-12-01 11:59:16 +02:00
Mahmoud-Emad
8fc560ae78 feat: add docs landing page slug handling
- Add function to find first doc in sidebar
- Pass found doc ID to process_page
- Set slug: / for landing page in frontmatter
2025-12-01 11:54:02 +02:00
ed785c79df ... 2025-12-01 10:35:46 +01:00
d53043dd65 ... 2025-12-01 05:28:15 +01:00
0a731f83e5 ... 2025-12-01 05:27:29 +01:00
Mahmoud-Emad
ed9ff35807 refactor: Improve navigation label generation
- Generate human-readable nav label
- Use title_case for page names without titles
2025-11-30 17:33:17 +02:00
Mahmoud-Emad
e2c2a560c8 feat: Refactor docusaurus playbook and sidebar JSON serialization
- Extract playbook action processing into separate functions
- Add auto-export for Atlas collections
- Simplify sidebar JSON serialization
- Update sidebar navigation item structure
2025-11-30 17:31:41 +02:00
5dcdf72310 Merge branch 'fix/install-hero-latest' into development_hetzner
* fix/install-hero-latest:
  fix: use GitHub 'latest' release URL in install_hero.sh
2025-11-30 15:59:35 +01:00
b6c883b5ac Merge branch 'development_k3s' into development_hetzner
* development_k3s:
  feat: Add K3s installer with complete lifecycle management
  feat: Add K3s installer with complete lifecycle management
  fixing startupcmd
  fix actions
  feat(k3s-installer)
2025-11-30 15:58:41 +01:00
78e4fade03 Merge branch 'development' into development_hetzner
* development:
  ...
  ...
  ...
  ...
  ...
2025-11-30 15:58:18 +01:00
0ca87c5f32 ... 2025-11-30 09:19:10 +01:00
5b2069c560 ... 2025-11-30 08:59:38 +01:00
0963910572 ... 2025-11-30 08:24:36 +01:00
394dd2c88e ... 2025-11-30 07:41:15 +01:00
d16aaa30db ... 2025-11-30 07:28:16 +01:00
d662e46a8d fix: use GitHub 'latest' release URL in install_hero.sh
- Remove hardcoded version, use releases/latest/download instead
- Always use musl builds for Linux (static binary works everywhere)
- Fix variable name bugs (OSNAME -> os_name, OSTYPE -> os_name)
- Only modify .zprofile on macOS (not Linux)
- Remove dead code
2025-11-28 18:06:01 +01:00
18da5823b7 ... 2025-11-28 14:18:16 +01:00
Mahmoud-Emad
1e9de962ad docs: Update Hetzner examples documentation
- Refactor Hetzner examples to use environment variables
- Clarify SSH key configuration for Hetzner
- Improve documentation structure and readability
2025-11-28 11:14:36 +02:00
Mahmoud-Emad
b9dc8996f5 feat: Improve Ubuntu installation and SSH execution
- Update example configuration comments
- Refactor server rescue check to use file_exists
- Add Ubuntu installation timeout and polling constants
- Implement non-interactive installation script execution
- Enhance SSH execution with argument parsing
- Add check to skip reinstallation if Ubuntu is already installed
- Copy SSH key to new system during installation
- Poll for installation completion with progress updates
- Use `node.exec` instead of `node.exec_interactive`
- Use `execvp` correctly for shell execution
- Recreate node connection after server reboot
- Adjust SSH wait timeout to milliseconds
2025-11-28 10:37:47 +02:00
7c03226054 ... 2025-11-28 09:37:21 +01:00
fc13f3e6ae ... 2025-11-28 09:27:19 +01:00
0414ea85df ... 2025-11-28 09:01:58 +01:00
60e2230448 ... 2025-11-28 05:47:47 +01:00
d9ad57985d Merge branch 'development' of github.com:incubaid/herolib into development 2025-11-28 05:42:38 +01:00
8368592267 ... 2025-11-28 05:42:35 +01:00
peternashaat
b9b8e7ab75 feat: Add K3s installer with complete lifecycle management
Implemented a production-ready K3s Kubernetes installer with full lifecycle
support including installation, startup management, and cleanup.

Key features:
- Install first master (cluster init), join additional masters (HA), and workers
- Systemd service management via StartupManager abstraction
- IPv6 support with Mycelium interface auto-detection
- Robust destroy/cleanup with proper ordering to prevent hanging
- Complete removal of services, processes, network interfaces, and data
2025-11-27 14:01:53 +01:00
peternashaat
dc2f8c2976 feat: Add K3s installer with complete lifecycle management
Implemented a production-ready K3s Kubernetes installer with full lifecycle
support including installation, startup management, and cleanup.

Key features:
- Install first master (cluster init), join additional masters (HA), and workers
- Systemd service management via StartupManager abstraction
- IPv6 support with Mycelium interface auto-detection
- Robust destroy/cleanup with proper ordering to prevent hanging
- Complete removal of services, processes, network interfaces, and data
2025-11-27 14:01:22 +01:00
Omdanii
fc592a2e27 Merge pull request #217 from Incubaid/development-docs
Enhance AI Prompts Files
2025-11-27 09:38:03 +02:00
Scott Yeager
0269277ac8 bump version to 1.0.38 2025-11-26 14:53:40 -08:00
Scott Yeager
ee0e7d44fd Fix release script 2025-11-26 14:53:29 -08:00
Scott Yeager
28f00d3dc6 Add build flow doc 2025-11-26 14:52:09 -08:00
Scott Yeager
a30646e3b1 Remove unused glibc upload 2025-11-26 14:02:39 -08:00
Scott Yeager
c7ae0ed393 Update workflow for single static build on Linux 2025-11-26 13:55:48 -08:00
805c900b02 Merge pull request #213 from Incubaid/development_linuxname
Rename "linux"
2025-11-26 13:51:24 -08:00
ab5fe67cc2 ... 2025-11-26 21:40:21 +01:00
peternashaat
449213681e fixing startupcmd 2025-11-26 14:51:53 +00:00
mik-tf
72ab099291 docs: update docs with latest herolib features 2025-11-26 09:10:14 -05:00
mik-tf
007361deab feat: Update AI prompts with Atlas integration details and code example fixes 2025-11-26 09:08:11 -05:00
mik-tf
8a458c6b3f feat: Update Docusaurus ebook manual to reflect Atlas integration and current pipeline 2025-11-26 08:47:32 -05:00
peternashaat
d69023e2c9 fix actions 2025-11-26 12:56:29 +00:00
peternashaat
3f09aad045 feat(k3s-installer) 2025-11-26 11:55:57 +00:00
Omdanii
aa434fddee Merge pull request #214 from Incubaid/development_fix_codeparser_tests
refactor: Improve const and param parsing logic
2025-11-26 12:28:52 +02:00
Mahmoud-Emad
deca6387f2 refactor: Improve const and param parsing logic
- Strip 'const ' prefix from const name
- Handle empty string for void param return type
- Handle empty split for void param return type
- Rename test functions to check functions
- Add `!` to functions that can return errors
2025-11-26 10:49:27 +02:00
Scott Yeager
dd293ce387 Rename "linux" 2025-11-25 21:30:01 -08:00
a6d746319c /// 2025-11-25 20:10:31 +01:00
0e20b9696a ... 2025-11-25 19:19:35 +01:00
b3e673b38f ... 2025-11-25 18:53:18 +01:00
c94be548bf Merge branch 'development_nile_installers' into development
* development_nile_installers:
  fix ci
  feat: Add reset functionality to startup commands
  feat(cryptpad): Refactor installer configuration logic
  feat: Add PostgreSQL support for Gitea installer
  feat: Add Gitea Kubernetes installer
  feat(cryptpad): Refactor installer for dynamic configuration
2025-11-25 18:40:44 +01:00
8472d20609 Merge branch 'development_heropods' into development
* development_heropods: (21 commits)
  test: Ignore virt/heropods/network_test.v in CI
  feat: implement container keep-alive feature
  test: Add comprehensive heropods network and container tests
  refactor: Refactor Mycelium configuration and dependencies
  feat: Add Mycelium IPv6 overlay networking
  test: Replace hero binary checks with network test
  feat: Add iptables FORWARD rules for bridge
  Revert "feat: Add `pods` command for container management"
  feat: Add `pods` command for container management
  chore: Enable execution of cmd_run
  feat: Add `run` command for Heroscript execution
  feat: Separate initialization and configuration
  refactor: Remove hero binary installation from rootfs
  refactor: Integrate logger and refactor network operations
  feat: Implement container networking and improve lifecycle
  feat: Auto-install hero binary in containers
  feat: Add container management actions for heropods
  feat: Add heropods library to plbook
  refactor: Rename heropods variable and method
  refactor: Rename container factory to heropods
  ...
2025-11-25 18:40:41 +01:00
27279f8959 Merge branch 'development_gitea_installer' into development_nile_installers
* development_gitea_installer:
  feat: Add PostgreSQL support for Gitea installer
  feat: Add Gitea Kubernetes installer
2025-11-25 18:39:42 +01:00
7d4dc2496c Merge branch 'development_cryptpad' into development_nile_installers
* development_cryptpad:
  feat(cryptpad): Refactor installer configuration logic
  feat(cryptpad): Refactor installer for dynamic configuration
2025-11-25 18:39:27 +01:00
3547f04a79 Merge branch 'development_heropods' into development_nile_installers
* development_heropods: (21 commits)
  test: Ignore virt/heropods/network_test.v in CI
  feat: implement container keep-alive feature
  test: Add comprehensive heropods network and container tests
  refactor: Refactor Mycelium configuration and dependencies
  feat: Add Mycelium IPv6 overlay networking
  test: Replace hero binary checks with network test
  feat: Add iptables FORWARD rules for bridge
  Revert "feat: Add `pods` command for container management"
  feat: Add `pods` command for container management
  chore: Enable execution of cmd_run
  feat: Add `run` command for Heroscript execution
  feat: Separate initialization and configuration
  refactor: Remove hero binary installation from rootfs
  refactor: Integrate logger and refactor network operations
  feat: Implement container networking and improve lifecycle
  feat: Auto-install hero binary in containers
  feat: Add container management actions for heropods
  feat: Add heropods library to plbook
  refactor: Rename heropods variable and method
  refactor: Rename container factory to heropods
  ...
2025-11-25 18:39:08 +01:00
253e26aec6 Merge branch 'development' into development_nile_installers
* development: (27 commits)
  ...
  ...
  fix: Ignore regex_convert_test.v test
  refactor: Replace codewalker with pathlib and filemap
  ...
  ...
  ...
  ...
  ...
  ...
  ...
  ...
  ...
  ...
  codewalker
  fix: Iterate over product requirement documents directly
  ...
  ...
  ...
  ...
  ...
2025-11-25 18:38:53 +01:00
a96d6e8aaa Merge branch 'development' of github.com:incubaid/herolib into development
* 'development' of github.com:incubaid/herolib:
  fix: Ignore regex_convert_test.v test
  refactor: Replace codewalker with pathlib and filemap
2025-11-25 18:38:27 +01:00
9fe669c5b8 ... 2025-11-25 18:38:21 +01:00
Timur Gordon
7e9bc1c41e fix ci 2025-11-25 14:55:00 +01:00
Timur Gordon
ee64a9fc58 Merge pull request #205 from Incubaid/development_fix_zinit
fix: Zinit client error when creating service
2025-11-25 14:41:51 +01:00
769c88adc8 ... 2025-11-25 14:08:52 +01:00
Mahmoud-Emad
520769a63e fix: Ignore regex_convert_test.v test 2025-11-25 14:55:18 +02:00
Mahmoud-Emad
1399d53748 refactor: Replace codewalker with pathlib and filemap
- Use pathlib for directory listing and filtering
- Use filemap for building file trees from selected directories
- Update build_file_map to use pathlib for recursive file listing
- Handle filemap building for standalone files and selected directories
2025-11-25 14:48:12 +02:00
Mahmoud-Emad
9f75a454fa test: Ignore virt/heropods/network_test.v in CI
- Add virt/heropods/network_test.v to ignored tests
- Ignore test requiring root for network bridge operations
2025-11-25 12:43:13 +00:00
Mahmoud-Emad
9a5973d366 feat: implement container keep-alive feature
- Add `keep_alive` parameter to `container_start`
- Implement logic to restart containers with `tail -f /dev/null` after successful entrypoint exit
- Update `podman_pull_and_export` to also extract image metadata
- Enhance `create_crun_config` to use extracted image metadata (ENTRYPOINT, CMD, ENV)
- Refactor test suite to use `keep_alive: true` for Alpine containers
2025-11-25 13:59:45 +02:00
fc41d3c62c ... 2025-11-25 06:13:56 +01:00
74146177e3 Merge branch 'development' of github.com:incubaid/herolib into development 2025-11-25 06:10:42 +01:00
c755821e34 ... 2025-11-25 06:10:17 +01:00
50a770c3ca ... 2025-11-25 06:03:37 +01:00
22dfcf4afa ... 2025-11-25 06:01:26 +01:00
b09e3ec0e1 ... 2025-11-25 05:51:55 +01:00
de7e1abcba ... 2025-11-25 05:44:58 +01:00
03d9e97008 ... 2025-11-25 05:23:17 +01:00
43eb15be7a ... 2025-11-25 05:13:02 +01:00
Mahmoud-Emad
76876049be test: Add comprehensive heropods network and container tests
- Add wait_for_process_ready to container start
- Reduce sigterm and stop check timeouts
- Update default container base directory
- Introduce new heropods test suite with multiple tests
- Add tests for initialization and custom network config
- Add tests for Docker image pull and container creation
- Add tests for container lifecycle (start, stop, delete)
- Add tests for container command execution
- Add tests for network IP allocation
- Add tests for IPv4 connectivity
- Add tests for container deletion and IP cleanup
- Add tests for bridge network setup and NAT rules
- Add tests for IP pool management
- Add tests for custom bridge configuration
2025-11-24 14:02:36 +02:00
803828e808 ... 2025-11-24 07:09:54 +01:00
9343772bc5 ... 2025-11-24 06:08:05 +01:00
d282a5dc95 codewalker 2025-11-24 05:48:13 +01:00
Mahmoud-Emad
dd7baa59b0 Merge branch 'development' into development_heropods 2025-11-23 13:06:50 +02:00
Mahmoud-Emad
69264adc3d fix: Iterate over product requirement documents directly
- Iterate over PRD objects instead of just IDs
- Pass PRD ID to delete function correctly
2025-11-23 12:13:25 +02:00
Mahmoud-Emad
3f943de9ed Merge branch 'development_nile_installers' into development_fix_zinit 2025-11-23 11:08:31 +02:00
Mahmoud-Emad
feffc09f73 Merge branch 'development' into development_nile_installers 2025-11-23 11:06:51 +02:00
Mahmoud-Emad
f11e0c689a Merge branch 'development' into development_nile_installers 2025-11-23 11:06:33 +02:00
Mahmoud-Emad
7c9f7c7568 Merge branch 'development_fix_zinit' of github.com:incubaid/herolib into development_fix_zinit 2025-11-23 11:01:59 +02:00
Mahmoud-Emad
dcd5af4d5f feat: Add reset functionality to startup commands
- Add `reset` boolean parameter to `StartArgs` struct
- Pass `reset` parameter to `startupcmd` calls
- Update service creation logic to handle `reset` flag
- Modify `install_start` and `restart` to pass `reset` parameter
2025-11-23 11:01:47 +02:00
4402cba8ac ... 2025-11-23 08:29:37 +01:00
01639853ce ... 2025-11-23 07:18:45 +01:00
0a25fc95b5 ... 2025-11-23 06:38:12 +01:00
9b5301f2c3 ... 2025-11-23 05:52:28 +01:00
2998a6e806 ... 2025-11-23 05:03:32 +01:00
0916ff07f8 ... 2025-11-23 05:01:31 +01:00
679108eb9e ... 2025-11-23 04:46:40 +01:00
1d4770aca5 ... 2025-11-23 04:43:08 +01:00
61a3677883 ... 2025-11-23 04:22:25 +01:00
27d2723023 .. 2025-11-22 18:32:19 +01:00
3d8effeac7 ... 2025-11-22 11:58:46 +02:00
a080fa8330 Merge branch 'development_zosbuilder' into development 2025-11-22 05:39:44 +02:00
d1584e929e Merge branch 'development' into development_fix_zinit
* development:
  ....
2025-11-22 05:37:21 +02:00
8733bc3fa8 Merge branch 'development' of github.com:incubaid/herolib into development
* 'development' of github.com:incubaid/herolib:
  refactor: Simplify default server retrieval
  test: Clear test database before running test
  test: Remove risks from PRD tests
  refactor: Pass rclone name as keyword argument
  test: Update test and script URL
  Refactor the herolib repo:
  test: Make page_exists call explicit
  test: Update image link assertion
  refactor: Extract heroscript path handling logic
  refactor: Keep file extensions when getting files
  refactor: Update image assertion syntax
  feat: Validate single input method for hero run
  feat: add cmd_run for heroscript execution
2025-11-22 05:36:12 +02:00
3ecb8c1130 .... 2025-11-22 05:36:04 +02:00
Mahmoud-Emad
26528a889d refactor: Update get calls and clean up debug
- Add `create: true` to get calls
- Remove commented-out print_backtrace
- Remove debug print for socket closure
2025-11-20 14:00:29 +02:00
Timur Gordon
41e3d2afe4 Merge branch 'development_nile_installers' into development_fix_zinit 2025-11-20 07:56:48 +01:00
Mahmoud-Emad
8daca7328d refactor: Improve service startup and management logic
- Add `create: true` to service `get` calls
- Update `running_check` to use `curl` for HTTP status code
- Ensure redis addresses have `redis://` prefix
- Clean up and re-create zinit services before starting
- Remove redundant `service_monitor` call in `startupmanager.start`
2025-11-19 17:08:49 +02:00
Timur Gordon
86da2cd435 chore: remove test installer and update template escape sequence
- Remove tester installer from playcmds factory
- Update template to use ^^ escape for @[params] annotation
- Format various model and actions files
2025-11-19 15:51:20 +01:00
Timur Gordon
a5c4b8f6f8 refactor: merge action handling blocks in play() functions
Merge the two separate if blocks for handling actions into a single block
since they both use the same logic for getting the name parameter with
get_default('name', 'default').

Changes:
- Combine destroy/install/build and start/stop/restart/lifecycle blocks
- All actions now use consistent name parameter handling
- Reduces code duplication in play() functions

Updated files:
- All 5 horus installer factory files
- Generator template objname_factory_.vtemplate
2025-11-19 15:44:50 +01:00
Timur Gordon
856a6202ee fix: escape @ symbol in template for InstallArgs annotation
Use @@ instead of @ in template to properly output @[params] in generated code.
V templates require double @@ to escape the @ symbol.
2025-11-19 15:17:31 +01:00
Timur Gordon
a40e172457 refactor: update installer generator templates to instance-based API
Update generator templates to produce installers following the new pattern:

Actions template (objname_actions.vtemplate):
- Convert all functions to methods on the config struct
- startupcmd() -> (self &Struct) startupcmd()
- running() -> (self &Struct) running_check()
- start_pre/post, stop_pre/post -> methods on struct
- installed(), install(), build(), destroy() -> methods on struct
- Add InstallArgs struct with reset parameter
- Remove get()! calls, use self instead

Factory template (objname_factory_.vtemplate):
- Update play() to get name parameter for all actions
- Call instance methods instead of module-level functions
- Add support for start_pre, start_post, stop_pre, stop_post actions
- Update start(), stop(), running() to use self.method() calls
- Remove duplicate InstallArgs and wrapper methods
- Use self.running_check() instead of running()

All newly generated installers will now follow the consistent
instance-based pattern with proper lifecycle hook support.
2025-11-19 15:09:24 +01:00
Mahmoud-Emad
012a59b3d8 Merge branch 'development_nile_installers' into development_fix_zinit 2025-11-19 16:04:30 +02:00
Mahmoud-Emad
6334036b79 Merge branch 'development' into development_fix_zinit 2025-11-19 15:18:23 +02:00
Mahmoud-Emad
df462174e5 refactor: Refactor Mycelium configuration and dependencies
- Flatten MyceliumConfig struct into HeroPods
- Remove Mycelium installer and service management logic
- Update Mycelium initialization to check for prerequisites only
- Adjust peers configuration to be comma-separated string
2025-11-19 15:17:39 +02:00
Mahmoud-Emad
1452d65f48 feat: Add Mycelium IPv6 overlay networking
- Integrate Mycelium IPv6 overlay networking
- Add Mycelium configuration options to HeroPods
- Enable Mycelium setup and cleanup for containers
- Include Mycelium examples and documentation
2025-11-19 14:23:06 +02:00
Timur Gordon
fcb178156b rename some installers, fix installer service startup w/ zinit 2025-11-19 11:42:55 +01:00
Timur Gordon
28313ad22f refactor: convert horus installers to instance-based API
- Convert all module-level functions to methods on config structs
- Add InstallArgs struct with reset parameter to actions files
- Update factory play() functions to call instance methods with name parameter
- Remove duplicate InstallArgs and wrapper methods from factory files
- Add support for start_pre, start_post, stop_pre, stop_post as callable actions
- Rename running() to running_check() to avoid conflicts
- All lifecycle methods (install, destroy, build, start, stop, etc.) now accept optional name parameter

Affected installers:
- coordinator
- supervisor
- herorunner
- osirisrunner
- salrunner

This provides a cleaner, more consistent API where all installer actions
can be called on specific configuration instances from heroscript files.
2025-11-19 11:03:36 +01:00
Mahmoud-Emad
9986dca758 test: Replace hero binary checks with network test
- Test network connectivity using wget
- Removed checks for hero binary existence and version
2025-11-19 11:03:17 +02:00
Mahmoud-Emad
9af9ab40b5 feat: Add iptables FORWARD rules for bridge
- Allow traffic from bridge to external interface
- Allow established traffic from external to bridge
- Allow traffic between containers on same bridge
2025-11-19 10:50:09 +02:00
Mahmoud-Emad
4b5a9741a0 Revert "feat: Add pods command for container management"
This reverts commit 11c3ea9ca5.
2025-11-18 16:26:49 +02:00
Mahmoud-Emad
11c3ea9ca5 feat: Add pods command for container management
- Implement `hero pods` CLI command
- Add subcommands for ps, images, create, start, stop, rm, exec, inspect
- Add flags for container creation and removal
2025-11-18 16:09:20 +02:00
Mahmoud-Emad
e7a38e555b Merge branch 'development' into development_heropods 2025-11-18 12:41:37 +02:00
Mahmoud-Emad
adb012e9cf refactor: Simplify default server retrieval
- Remove unused logic for default server lookup
- Consolidate server retrieval for Cryptpad and ElementChat
- Update default server assignment logic
2025-11-18 12:37:26 +02:00
Mahmoud-Emad
8ca7985753 refactor: Update default coordinator name
- Change default `ArgsGet.name` to 'default'
- Remove logic for overriding `args.name` with `coordinator_default`
- Set `coordinator_default` directly to `args.name`
2025-11-18 12:34:47 +02:00
Mahmoud-Emad
82378961db refactor: Remove unused default name logic
- Remove conditional logic for 'default' name
- Simplify 'get' function argument handling
2025-11-18 12:33:14 +02:00
Mahmoud-Emad
f9a2ebf24b chore: Refactor coordinator configuration and status reporting
- Update default coordinator name to 'coordinator'
- Improve status reporting by using dedicated variables
- Adjust `zinit.get` call to use `create: true`
- Set `zinit_default` based on `args.name` when 'default' is provided
- Update `coordinatorServer.name` default to 'coordinator'
- Make 'coordinator' the default for `ArgsGet.name`
- Use `coordinator_default` for `ArgsGet.name` if set
- Adjust `CoordinatorServer.binary_path` default
- Update `zinit.get` to use `create: true`
- Log socket closure for debugging
- Remove unused import `incubaid.herolib.core.texttools`
2025-11-18 11:50:52 +02:00
Mahmoud-Emad
9dc33e3ce9 Merge branch 'development' into development_nile_installers 2025-11-18 10:02:23 +02:00
Mahmoud-Emad
ae4997d80a Merge branch 'development' into development_heropods 2025-11-18 09:55:33 +02:00
Timur Gordon
b26c1f74e3 Merge branch 'development_nile_installers' of github.com:Incubaid/herolib into development_nile_installers 2025-11-17 16:02:44 +01:00
Timur Gordon
bf6dec48f1 add other horus installers, create examples, test startup 2025-11-17 15:57:40 +01:00
Mahmoud-Emad
3a05dc8ae0 test: Clear test database before running test
- Flush the Redis database for a clean test state
2025-11-17 15:58:01 +02:00
Mahmoud-Emad
5559bd4f2f test: Remove risks from PRD tests
- Remove assertions for risks in PRD tests
- Remove risk map initialization and population
- Update PRD encoding/decoding test
2025-11-17 15:40:14 +02:00
Mahmoud-Emad
9d79408931 refactor: Pass rclone name as keyword argument
- Update rclone.new call to use named argument
2025-11-17 15:28:47 +02:00
Mahmoud-Emad
f5c2b306b8 test: Update test and script URL
- Remove frontmatter test due to disabled parsing
- Update install script URL
2025-11-17 15:23:08 +02:00
Mahmoud-Emad
49868a18e1 Refactor the herolib repo:
- Removed the unused files
- Updated the README
- Added all needed scripts in /scripts dir
- Update script paths in CI configuration
- Update script paths in Go code
- Move installation scripts to scripts directory
- Change script path from ./install_v.sh to ./scripts/install_v.sh
2025-11-17 15:11:55 +02:00
Mahmoud-Emad
2ab0dfa6b8 test: Make page_exists call explicit
- Add '!' to col.page_exists('intro') call
2025-11-17 14:56:43 +02:00
Mahmoud-Emad
82375f9b89 test: Update image link assertion
- Change assertion for image link detection
- Use `file_type` instead of `is_image_link`
2025-11-17 14:51:15 +02:00
peternashaat
f664823a90 refactor: Remove Redis installation from coordinator, improve Rust detection
- Remove all Redis installation logic from coordinator installer
- Add osal.cmd_exists() check before installing Rust
- Update docs: Redis must be pre-installed
- Add reset flag documentation for forcing rebuilds
- Coordinator now only installs Rust and builds binary
2025-11-17 12:50:59 +00:00
Mahmoud-Emad
9b2e9114b8 refactor: Extract heroscript path handling logic
- Add helper function to expand and validate file paths
- Add helper function to validate heroscript content
- Add helper function to run heroscript from file
- Inline scripts now validated before execution
- File-based scripts now use the new run_from_file helper
2025-11-17 14:43:08 +02:00
Mahmoud-Emad
8dc2b360ba refactor: Keep file extensions when getting files
- Use `name_fix_keepext` instead of `name_fix`
- Update calls to `image_get`, `file_get`, and `file_or_image_get`
- Update checks in `image_exists`, `file_exists`, and `file_or_image_exists`
2025-11-17 13:39:25 +02:00
Mahmoud-Emad
49e48e7aca refactor: Update image assertion syntax
- Add '!' to image_exists calls
- Update image file name access
2025-11-17 12:18:26 +02:00
Mahmoud-Emad
586c6db34e Merge branch 'development' into development_heropods 2025-11-17 12:08:06 +02:00
Mahmoud-Emad
122a864601 Merge branch 'development' into development_heropods 2025-11-17 12:05:53 +02:00
Omdanii
571bc31179 Merge pull request #202 from Incubaid/development_herorun_cmd
Add Support for `hero run` Command
2025-11-17 12:03:28 +02:00
Mahmoud-Emad
35734b5ebc feat: Validate single input method for hero run
- Add validation for multiple input methods
- Improve error message for no script provided
- Update usage instructions in help message
2025-11-17 12:02:16 +02:00
Mahmoud-Emad
15f81aca41 feat: add cmd_run for heroscript execution
- Add `cmd_run` function to `herocmds` module
- Allow running heroscripts from inline strings via `-s` flag
- Enable running heroscripts from file paths via `-p` flag or as arguments
- Add `-r` flag to reset before running
2025-11-17 11:53:48 +02:00
peternashaat
1484fec898 - Renamed HerocoordinatorServer to CoordinatorServer 2025-11-17 07:58:28 +00:00
peternashaat
06fcfa5b50 feat: add dynamic Redis configuration to coordinator installer
- Add redis_port field to CoordinatorServer struct
- Refactor ensure_redis_running() to use @[params] pattern
- Pass redis_port and redis_addr dynamically from config
- Follow same pattern as cryptpad installer for consistency
2025-11-16 13:34:38 +00:00
peternashaat
a26f0a93fe refactor: improve coordinator installer code quality
- Remove unused imports (texttools, paramsparser)
- Move ensure_redis_running() helper to better location
- Add comments to lifecycle hook functions
- Improve error handling for binary copy operation
- Add documentation to obj_init function
2025-11-16 13:18:32 +00:00
peternashaat
eb0fe4d3a9 refactor: move coordinator installer to horus directory and fix Redis installer permissions
- Moved coordinator installer from installers/infra to installers/horus
- Renamed HerocoordinatorServer to CoordinatorServer
- Fixed Redis installer permissions for /var/lib/redis directory
- Integrated coordinator with new modular Redis installer
2025-11-16 13:05:29 +00:00
8a7987b9c3 ... 2025-11-15 07:09:56 +02:00
70d581fb57 Merge branch 'development' of github.com:incubaid/herolib into development 2025-11-15 06:16:01 +02:00
d267c1131f ... 2025-11-15 06:15:02 +02:00
1ac9092eed adds zosbuilder
Signed-off-by: Ashraf Fouda <ashraf.m.fouda@gmail.com>
2025-11-15 01:19:33 +02:00
peternashaat
bf79d6d198 feat: migrate Redis installer and add to coordinator dependencies
- Migrated Redis to new installer pattern with fixed config template
- Coordinator now auto-installs Redis if missing
- Added progress indicators and consolidated examples
2025-11-14 13:29:22 +00:00
peternashaat
eada09135c feat: migrate Redis installer and integrate into coordinator
- Created coordinator installer
- Migrated Redis installer to new modular pattern (_model.v, _actions.v, _factory_.v)
- Fixed Redis config template for 7.0.15 compatibility (commented out unsupported directives)
- Added Redis dependency check to coordinator installer
- Coordinator now auto-installs and starts Redis if not available
- Added progress indicators to coordinator build process
- Consolidated Redis example scripts
- All tests passing: Redis installation, coordinator build, and idempotency verified
2025-11-14 13:25:35 +00:00
a447aeec43 Merge pull request #182 from Incubaid/development_installer
Update install script
2025-11-14 02:23:56 -08:00
Timur Gordon
78d848783a fix breaking code 2025-11-14 10:26:45 +01:00
Mahmoud-Emad
8c2b5a8f5e chore: Enable execution of cmd_run
- Uncomment herocmds.cmd_run(mut cmd)
2025-11-14 11:21:07 +02:00
Mahmoud-Emad
fcb5964f8d feat: Add run command for Heroscript execution
- Add `cmd_run` to execute heroscripts from files or inline
- Implement file path handling and inline script execution
- Add Linux platform check for HeroPods initialization
- Update documentation to reflect Linux-only requirement
2025-11-14 11:20:26 +02:00
e97e0d77be Merge branch 'development' into development_docusaurus_atlas
* development:
  Fix redis package name for alpine
  ...
2025-11-14 08:52:21 +02:00
16155480de Merge branch 'development' of github.com:incubaid/herolib into development
* 'development' of github.com:incubaid/herolib: (26 commits)
  Fix redis package name for alpine
  ...
  ...
  ...
  ...
  ...
  ...
  ...
  ...
  ...
  ...
  ...
  ...
  ...
  ...
  ...
  feat: Enhance docusaurus site generation with atlas client
  feat: Improve export self-containment and link handling
  ...
  feat: Add Atlas Export and AtlasClient example
  ...
2025-11-14 08:52:13 +02:00
e7611d4dc2 ... 2025-11-14 08:51:32 +02:00
Scott Yeager
45215b0abb Update installer 2025-11-13 08:04:17 -08:00
Scott Yeager
7246223e3b Use run_sudo everywhere 2025-11-12 05:37:56 -08:00
Scott Yeager
1958f24528 Add herolib version arg 2025-11-12 05:23:34 -08:00
c033cacd5b Fix redis package name for alpine 2025-11-12 05:11:01 -08:00
Mahmoud-Emad
d3f05c1834 feat: Separate initialization and configuration
- Move network defaults to obj_init
- Add initialize() method for heavy setup
- Improve separation of concerns for HeroPods initialization
2025-11-12 13:32:53 +02:00
Mahmoud-Emad
4bf16d6f70 refactor: Remove hero binary installation from rootfs
- Remove function `install_hero_in_rootfs`
- Remove call to `install_hero_in_rootfs`
2025-11-12 11:39:01 +02:00
Mahmoud-Emad
ad7e1980a5 refactor: Integrate logger and refactor network operations
- Replace console logging with logger.log calls
- Improve network bridge creation robustness
- Enhance network IP allocation and cleanup logic
- Refactor network cleanup for better concurrency handling
2025-11-12 11:28:56 +02:00
Mahmoud-Emad
7836a48ad4 feat: Implement container networking and improve lifecycle
- Add thread-safe network management for containers
- Implement graceful and forceful container stopping
- Enhance container creation and deletion logic
- Refine image management and metadata handling
- Add container name validation for security
2025-11-12 10:38:39 +02:00
Mahmoud-Emad
1d67522937 feat: Auto-install hero binary in containers
- Install hero binary into container rootfs
- Compile hero binary if not found on host
- Copy hero binary to container's /usr/local/bin
- Make hero binary executable in container
2025-11-11 12:48:34 +02:00
Mahmoud-Emad
e6c3ed93fa feat: Add container management actions for heropods
- Add processing for heropods.container_new
- Add processing for heropods.container_start
- Add processing for heropods.container_exec
- Add processing for heropods.container_stop
- Add processing for heropods.container_delete
2025-11-11 11:24:58 +02:00
Mahmoud-Emad
2fafd025eb feat: Add heropods library to plbook
- Import heropods library
- Play heropods library in plbook
2025-11-11 10:40:27 +02:00
Mahmoud-Emad
3ae980d4c5 refactor: Rename heropods variable and method
- Rename `factory` to `heropods_`
- Rename `factory.new` to `heropods_.container_new`
- Update error message for `heropods.new`
2025-11-11 10:11:01 +02:00
Mahmoud-Emad
e94734ecc7 refactor: Rename container factory to heropods
- Rename `factory` variable to `heropods_`
- Update calls from `factory.new` to `heropods_.container_new`
- Adjust error message for initialization
- Update print statements to reflect renaming
2025-11-11 10:08:59 +02:00
Mahmoud-Emad
deb1210405 refactor: Rename ContainerFactory to HeroPods
- Rename ContainerFactory struct to HeroPods
- Update method names and receiver types accordingly
- Adjust imports and internal references
2025-11-11 10:08:15 +02:00
Omdanii
759870e01e Merge pull request #196 from Incubaid/development_docusaurus_atlas
Docusaurus Atlas tool
2025-11-10 08:38:03 +02:00
891f3bf66d ... 2025-11-09 08:53:08 +04:00
3179d362fc ... 2025-11-09 08:47:11 +04:00
69d9949c39 ... 2025-11-09 08:20:11 +04:00
5d2adb1a2c ... 2025-11-09 08:17:00 +04:00
c409d42f64 ... 2025-11-09 07:43:44 +04:00
2dad87ad5e ... 2025-11-09 06:41:23 +04:00
fd5a348e20 ... 2025-11-09 06:36:05 +04:00
93fc823e00 ... 2025-11-09 06:25:44 +04:00
f40565c571 ... 2025-11-08 11:12:16 +04:00
5a6f3d323b ... 2025-11-07 07:58:53 +04:00
836a8f799e ... 2025-11-07 07:47:42 +04:00
b9a84ee8fc ... 2025-11-07 07:39:05 +04:00
0d3b4357ac ... 2025-11-07 07:24:38 +04:00
ea1a49ffd5 ... 2025-11-07 07:19:28 +04:00
f4de662fc2 ... 2025-11-07 07:00:23 +04:00
Mahmoud-Emad
a149845fc7 feat: Enhance docusaurus site generation with atlas client
- Add flags for development server and browser opening
- Introduce IDocClient interface for unified client access
- Implement atlas_client integration for Docusaurus
- Refactor link handling and image path resolution
- Update Docusaurus config with atlas client options
2025-11-06 15:44:09 +02:00
a2eaf6096e ... 2025-11-06 16:14:34 +04:00
Mahmoud-Emad
5fccd03ee7 Merge branch 'development_docusaurus_atlas' of github.com:incubaid/herolib into development_docusaurus_atlas 2025-11-06 10:51:42 +02:00
Mahmoud-Emad
347ebed5ea feat: Improve export self-containment and link handling
- Use absolute paths for path_relative calculations
- Validate links before export to populate page.links
- Copy cross-collection referenced pages for self-contained export
- Update export_link_path to generate local links for self-contained exports
- Remove page from visited map to allow re-inclusion in other contexts
2025-11-06 10:51:10 +02:00
b582bd03ef ... 2025-11-06 09:40:59 +04:00
Mahmoud-Emad
ac09648a5b feat: Add Atlas Export and AtlasClient example
- Add example for exporting Atlas collections
- Demonstrate using AtlasClient to read exported content
- Include examples for listing collections and pages
- Show reading page content and metadata via AtlasClient
2025-11-05 16:08:56 +02:00
Mahmoud-Emad
04e1e2375f refactor: Remove docusaurus dev server and path_meta flag
- Remove 'dev' flag from run command
- Remove 'path_meta' flag from run command
- Remove docusaurus integration from playcmds
- Add `validate_links` and `fix_links` to Atlas
- Refactor page link processing for clarity and export mode
2025-11-05 15:25:50 +02:00
Mahmoud-Emad
a2ac8c0027 refactor: Simplify text normalization comments
- Remove outdated comments related to normalization
- Update comments for clarity
2025-11-05 10:04:57 +02:00
Mahmoud-Emad
2150b93a80 refactor: Update name normalization logic
- Use texttools.name_fix instead of name_fix_no_underscore_no_ext
- Preserve underscores in normalized names
- Update documentation and tests to reflect changes
2025-11-05 10:01:18 +02:00
Mahmoud-Emad
10b9af578a feat: Add Docusaurus dev server integration
- Add 'dev' flag to run Docusaurus server
- Import docusaurus library
- Enable scan and export if 'dev' flag is set
- Handle export errors more gracefully
- Start Docusaurus dev server after export
2025-11-04 16:49:00 +02:00
Mahmoud-Emad
8bfb021939 feat: Support atlas_client module:
- Add client for atlas module
- Add unit tests to test the workflow
- Remove println statements from file_or_image_exists
- Remove println statements from link processing loop
2025-11-04 15:56:07 +02:00
Mahmoud-Emad
ecfe77a2dc refactor: Normalize page and collection names
- Use `name_fix_no_underscore_no_ext` for consistent naming
- Remove underscores and special characters from names
- Add tests for name normalization functions
- Ensure page and collection names are consistently formatted
- Update link parsing to use normalized names
2025-11-04 12:28:13 +02:00
peternashaat
683008da8f feat(cryptpad): Refactor installer configuration logic
Refactors the CryptPad installer to improve its configuration handling.

- The `hostname` and `namespace` are now derived from the installer's `name` property by default.
- Implemented name sanitization to remove special characters (`_`, `-`, `.`).
- Added validation to ensure the namespace does not contain invalid characters.
- Updated the factory's `reload` function to persist changes made to the installer object after its initial creation.

This change ensures consistent and predictable behavior, allowing for both default generation and manual override of configuration values.

Co-authored-by: Mahmoud-Emad <mahmmoud.hassanein@gmail.com>
2025-11-04 09:01:53 +00:00
Omdanii
ef14bc6d82 Merge pull request #184 from Incubaid/development_heroserver_errors
refactor: Update library paths
2025-11-03 23:21:42 +02:00
Mahmoud-Emad
bafc519cd7 feat: Add PostgreSQL support for Gitea installer
- Add PostgreSQL configuration options
- Generate PostgreSQL YAML when selected
- Verify PostgreSQL pod readiness
- Update documentation for PostgreSQL usage
- Add PostgreSQL service and pod definitions
2025-11-03 17:04:40 +02:00
Mahmoud-Emad
472e4bfaaa feat: Add Gitea Kubernetes installer
- Add Gitea installer module and types
- Implement installation and destruction logic
- Integrate with Kubernetes and TFGW
- Add example usage and documentation
2025-11-03 16:25:21 +02:00
peternashaat
e3c8d032f7 Merge remote-tracking branch 'origin/development' into development_cryptpad 2025-11-03 13:54:27 +00:00
Omdanii
7d72faa934 Merge pull request #193 from Incubaid/development_element_and_matrix
feat: Implement Element Chat Kubernetes installer
2025-11-03 15:51:23 +02:00
Mahmoud-Emad
8e5507b04e fix: Update element chat config and defaults
- Update element chat default name to 'elementchat'
- Sanitize element chat name from invalid characters
- Set default namespace based on sanitized name
- Validate namespace for invalid characters
- Update documentation with new default values
2025-11-03 15:49:54 +02:00
peternashaat
6746d885f8 feat(cryptpad): Refactor installer for dynamic configuration
This commit refactors the CryptPad Kubernetes installer to be more dynamic and configurable structure.

Key changes include:
-   **Dynamic Configuration**: The installer now generates its configuration based on parameters passed from the `.vsh` script, with sensible defaults for any unspecifie
d values.
-   **Templated `config.js`**: Introduced a new `config.js` template to allow for greater flexibility and easier maintenance of the CryptPad configuration.
-   **Improved Code Structure**: The source code has been updated to be more modular and maintainable.
-   **Updated Documentation**: The `README.md` has been updated to include instructions on how to run the installer and customize the installation.

Co-authored-by: Mahmoud-Emad <mahmmoud.hassanein@gmail.com>
2025-11-03 13:12:46 +00:00
Mahmoud-Emad
2e56311cd0 refactor: Prefix hostnames with instance name
- Prefix matrix_hostname with mycfg.name
- Prefix element_hostname with mycfg.name

Co-authored-by: peternashaaat <peternashaaat@gmail.com>
2025-11-03 12:24:59 +02:00
Mahmoud-Emad
4d3071f2d2 feat: Update installer name
- Change installer name from 'myelementchat' to 'kristof'

Co-authored-by: peternashaaat <peternashaaat@gmail.com>
2025-11-02 17:29:20 +02:00
Mahmoud-Emad
3ee0e5b29c feat: Implement Element Chat Kubernetes installer
- Add Element Chat installer module
- Integrate Conduit and Element Web deployments
- Support TFGW integration for FQDNs and TLS
- Implement installation and destruction logic
- Generate Kubernetes YAML from templates

Co-authored-by: peternashaaat <peternashaaat@gmail.com>
2025-11-02 17:24:01 +02:00
Omdanii
672ff886d4 Merge pull request #192 from Incubaid/development_openrouter
Adding Cryptpad installer and finalizing the Kubernetes client
2025-11-02 13:54:21 +02:00
Mahmoud-Emad
44c8793074 refactor: Update cryptpad installer code
- Use installer.kube_client for Kubernetes operations
- Remove redundant startupmanager calls
- Simplify `delete_resource` command
- Add default values for installer name and hostname
- Refactor `get` function to use new arguments correctly
- Remove commented out example code and unused imports
- Change the factory file<REQUIRED> to load the default instance name
- Update the README file of the installer

Co-authored-by: peternahaaat <peternashaaat@gmail.com>
2025-11-02 13:37:38 +02:00
Mahmoud-Emad
86549480b5 Merge branch 'development_openrouter' of github.com:incubaid/herolib into development_openrouter 2025-10-30 18:00:54 +03:00
Mahmoud-Emad
80108d4b36 refactor: Refactor Kubernetes client and CryptPad installer
- Replace kubectl exec calls with Kubernetes client methods
- Improve error handling and logging in Kubernetes client
- Enhance node information retrieval and parsing
- Add comprehensive unit tests for Kubernetes client and Node structs
- Refine YAML validation to allow custom resource definitions
- Update CryptPad installer to use the refactored Kubernetes client
2025-10-30 17:58:03 +03:00
peternashaat
81adc60eea feat(cryptpad): Use constants for deployment retry logic
Refactor the installer to use global constants for the maximum number of retries and the check interval when verifying deployments.

This change removes hardcoded values from the FQDN and deployment status checks, improving maintainability and centralizing configuration.
2025-10-30 13:21:49 +00:00
peternashaat
82d37374d8 Cryptpad installer 2025-10-30 11:46:15 +00:00
Mahmoud-Emad
c556cc71d4 feat: Implement Kubernetes client and example
- Add Kubernetes client module for interacting with kubectl
- Implement methods to get cluster info, pods, deployments, and services
- Create a Kubernetes example script demonstrating client usage
- Add JSON response structs for parsing kubectl output
- Define runtime resource structs (Pod, Deployment, Service) for structured data
- Include comprehensive unit tests for data structures and client logic
2025-10-29 16:46:37 +03:00
Mahmoud-Emad
79b78aa6fe feat: Implement Kubernetes installer for kubectl
- Add install functionality for kubectl
- Implement destroy functionality for kubectl
- Add platform-specific download URLs for kubectl
- Ensure .kube directory is created with correct permissions
2025-10-29 13:32:43 +03:00
Mahmoud-Emad
f6734a3568 chore: Remove openrouter client
- Remove call to openrouter.play from the main play function
- Used the OpenAI client instead
- Updated the examples
- Updated the README
2025-10-29 11:42:44 +03:00
0adb38a8a7 Merge branch 'development' into development_heroserver_errors
* development:
  ...
  ...
  ...
  ...
  ...
  ...
  ...
  refactor: Update OpenRouter client and examples
2025-10-29 12:10:23 +04:00
88f83cbfe2 ... 2025-10-29 12:09:53 +04:00
4e4abc055b ... 2025-10-29 09:49:49 +04:00
05c789da7e ... 2025-10-29 09:36:37 +04:00
9c8bcbff0c ... 2025-10-29 09:35:46 +04:00
fbed626771 ... 2025-10-29 09:28:27 +04:00
8583238fdb ... 2025-10-29 09:25:55 +04:00
c5f1d39958 ... 2025-10-29 07:53:34 +04:00
15ec641bc6 Merge branch 'development' into development_heroserver_errors
* development:
  ...
  ...
  ...
  ...
  ...
  ...
  ..
  ...
  ...
  ...
  ...
  ...
  ...
  atlas is working
  reverted
  ...
  ...
  ...
2025-10-29 07:05:50 +04:00
Mahmoud-Emad
4222dac72e refactor: Update OpenRouter client and examples
- Add error handling for client initialization
- Improve example scripts for clarity and robustness
- Refine client configuration and usage patterns
- Update documentation with current examples and features
- Enhance model handling and response processing
2025-10-28 22:40:37 +03:00
d1c0c8f03e ... 2025-10-26 23:44:04 +04:00
1973b58deb ... 2025-10-26 22:42:41 +04:00
46ce903d4d ... 2025-10-26 22:24:18 +04:00
9d1c347da7 ... 2025-10-26 21:18:39 +04:00
216eb262dd ... 2025-10-26 21:14:10 +04:00
b85ac9adc9 ... 2025-10-26 18:14:32 +04:00
79f2752b30 .. 2025-10-26 11:39:54 +04:00
d4911748ec ... 2025-10-26 11:37:24 +04:00
e574bcbc50 ... 2025-10-25 09:44:19 +04:00
9d2dedb2b6 ... 2025-10-25 09:03:03 +04:00
569d980336 ... 2025-10-25 08:51:57 +04:00
3df101afc7 ... 2025-10-24 16:54:43 +04:00
19fd4649be ... 2025-10-24 13:58:31 +04:00
Mahmoud-Emad
521596b29b refactor: Remove unused saved_content variable
- Remove redundant variable `saved_content`
- Simplify text concatenation logic
- Comment out unused '*' character handling
2025-10-23 17:45:33 +03:00
Mahmoud-Emad
53b5ee950f fix: Mark action element as processed
- Set action element to processed after content update
2025-10-23 17:43:38 +03:00
5cdac4d7fd atlas is working 2025-10-23 16:41:48 +02:00
581ae4808c reverted 2025-10-23 08:29:10 +02:00
bc26c88188 ... 2025-10-23 08:20:31 +02:00
f7ea3ec420 ... 2025-10-23 08:19:08 +02:00
091aef5859 ... 2025-10-23 07:48:20 +02:00
Mahmoud-Emad
c99831ee9b feat: Add virt/kubernetes directory
- Add virt/kubernetes directory
- Initialize Kubernetes integration setup
2025-10-22 21:46:57 +03:00
Mahmoud-Emad
4ab78c65e3 refactor: Update library paths
- Remove `lib/hero`
- Add `lib/hero/heromodels`
2025-10-22 21:41:47 +03:00
Omdanii
67d4137b61 Merge pull request #183 from Incubaid/development_heroserver_errors
fix: Improve error handling and optional crypto_client
2025-10-22 21:36:35 +03:00
Mahmoud-Emad
afbfa11516 refactor: Improve frontmatter and def parsing logic
- Save content before modifying
- Handle '*' character for defs correctly
- Re-enable frontmatter parsing for '---' and '+++'
- Re-enable frontmatter parsing for '---' and '+++' in paragraphs
2025-10-22 21:31:49 +03:00
Mahmoud-Emad
4f3a81b097 Merge branch 'development' into development_heroserver_errors 2025-10-22 21:15:17 +03:00
Mahmoud-Emad
0bfb5cfdd0 refactor: Update JSON parsing and schema inflation
- Use `json2.decode[json2.Any]` instead of `json2.raw_decode`
- Add `@[required]` to procedure function signatures
- Improve error handling for missing JSONRPC fields
- Update `encode` to use `prettify: true`
- Add checks for missing schema and content descriptor references
2025-10-22 21:14:29 +03:00
Mahmoud-Emad
d0ca0ca42d Merge branches 'development' and 'development' of github.com:incubaid/herolib into development 2025-10-22 11:06:24 +03:00
Mahmoud-Emad
98ba344d65 refactor: Use action_ directly instead of action alias
- Access action_ parameters directly
- Avoid creating a mutable alias for action_
2025-10-22 11:06:07 +03:00
fee3314653 Merge branch 'development' of github.com:incubaid/herolib into development 2025-10-22 09:38:51 +02:00
caedf2e2dd ... 2025-10-22 09:38:49 +02:00
Mahmoud-Emad
37f0aa0e96 feat: Implement dark mode theme and improve UI
- Add CSS variables for theming
- Implement dark mode toggle functionality
- Refactor styles for better organization and readability
- Update navigation bar with theme toggle button
- Enhance hero section with display-4 font size
- Adjust card styles for consistent appearance
- Improve alert and badge styling
- Make hero server title bold and larger
- Use Bootstrap 5 classes for consistent styling
- Add prefetch for Bootstrap JS
- Update `auth_enabled` default to false in server creation
2025-10-21 23:32:25 +03:00
Mahmoud-Emad
63c2efc921 feat: Group API methods and improve TOC
- Add method grouping by model/actor prefix
- Introduce DocMethodGroup struct for grouped methods
- Refactor TOC to display methods by groups
- Add collapsible sections for method groups and methods
- Improve CSS for better presentation of grouped content
2025-10-21 16:43:43 +03:00
Mahmoud-Emad
8ef9522676 refactor: Update method names and add curl example generation
- Rename API method names using dot notation
- Add endpoint_url and curl_example to DocMethod
- Implement generate_curl_example function
- Update DocMethod struct with new fields
2025-10-21 15:39:59 +03:00
Mahmoud-Emad
a120ef2676 refactor: Improve schema example generation and inflation
- Inflate methods to resolve $ref references
- Use schema-generated examples for requests
- Implement robust recursive schema example generation
- Add constants for example generation depth and property limits
- Utilize V's json2 module for JSON pretty-printing
2025-10-21 15:02:18 +03:00
Mahmoud-Emad
27c8273eec docs: Document doctree export and WARP guidelines
- Add documentation for doctree export functionality
- Include WARP.md with project guidelines and commands
2025-10-21 11:26:48 +03:00
Mahmoud-Emad
c1489fc491 fix: Improve error handling and optional crypto_client
- Add explicit error handling for HeroModels initialization
- Enhance error messages for HeroDB connection and ping failures
- Make crypto_client optional in HeroServer configuration
- Initialize crypto_client only when auth_enabled is true
- Ensure crypto_client is available before use in auth_submit
2025-10-21 11:10:30 +03:00
12c6aabed5 ... 2025-10-21 09:46:06 +02:00
67d13d081b ... 2025-10-21 09:30:37 +02:00
12ad7b1e6f ... 2025-10-21 09:30:22 +02:00
1cde14f640 ... 2025-10-21 09:12:00 +02:00
a5f8074411 ... 2025-10-21 08:51:27 +02:00
f69078a42e ... 2025-10-21 08:49:11 +02:00
Scott Yeager
9f3f1914ce Remove build workarounds 2025-10-20 13:59:21 -07:00
Scott Yeager
f2e1e7c11c Update install script 2025-10-20 13:59:21 -07:00
b538540cd4 Merge branch 'development' of github.com:incubaid/herolib into development 2025-10-19 16:28:37 +02:00
1a76c31865 ... 2025-10-19 16:28:35 +02:00
Mahmoud-Emad
f477fe46b3 feat: Update site page source references
- Update `site.page` src from "tech:introduction" to "mycelium_tech:introduction"
- Update `site.page` src from "tech:mycelium" to "mycelium_tech:mycelium"
2025-10-19 16:58:18 +03:00
Mahmoud-Emad
b18c6824d6 feat: Add announcement bar configuration
- Add AnnouncementBar struct and field to Configuration
- Add announcement.json file generation
- Implement play_announcement function for importing announcement config
- Improve fix_links to calculate relative paths dynamically
- Escape single quotes in YAML frontmatter fields
2025-10-16 17:38:18 +03:00
b2bc0d1b6a Merge branch 'development' of github.com:incubaid/herolib into development 2025-10-16 16:03:48 +04:00
f2f87eb7fd ... 2025-10-16 16:03:45 +04:00
Mahmoud-Emad
112894b24f Update the pages 2025-10-16 12:47:50 +03:00
4cfc018ace ... 2025-10-16 13:23:15 +04:00
05db43fe83 ... 2025-10-16 10:32:16 +04:00
c35ba97682 ... 2025-10-16 10:28:48 +04:00
f4711681dc ... 2025-10-16 10:12:02 +04:00
cb52bcfbe4 ... 2025-10-16 10:00:06 +04:00
099b21510d ... 2025-10-16 09:51:42 +04:00
91fdf9a774 ... 2025-10-16 09:45:42 +04:00
cf601283b1 ... 2025-10-16 09:25:03 +04:00
6918a02eff ... 2025-10-16 08:09:11 +04:00
Omdanii
b4971de5e9 Merge pull request #181 from Incubaid/development_herodocs_links
fix: Improve Docusaurus link generation logic
2025-10-15 17:38:35 +03:00
Mahmoud-Emad
9240e2ede8 fix: Improve Docusaurus link generation logic
- Add function to strip numeric prefixes from filenames
- Strip numeric prefixes from links for Docusaurus compatibility
- Fix same-collection relative links
- Convert collection:page links to relative paths
- Remove .md extensions from generated links
2025-10-15 16:44:02 +03:00
Mahmoud-Emad
446c54b0b5 feat: Improve Docusaurus link generation
- Add function to fix links for nested categories
- Adjust path generation for nested collections
- Remove .md extensions from Docusaurus links
- Conditionally apply name_fix to page paths
2025-10-15 04:26:29 +03:00
Scott Yeager
8edf8c9299 Delete extra file 2025-10-14 16:23:49 -07:00
Mahmoud-Emad
9c4520a645 Merge branch 'development' of github.com:incubaid/herolib into development 2025-10-15 02:08:17 +03:00
Mahmoud-Emad
fc9142b005 fix: Ensure pagepath ends with a slash
- Use section_current.path for default page path
- Append slash if pagepath is not empty and doesn't end with one
2025-10-15 02:07:52 +03:00
Scott Yeager
cc31ce0f6f Update install script to use new release file names 2025-10-14 15:17:11 -07:00
Scott Yeager
1688c4f9b0 bump version to 1.0.36 2025-10-14 14:37:14 -07:00
Scott Yeager
9a7b9b8a10 Fix release flow 2025-10-14 14:35:59 -07:00
Scott Yeager
2b5f53b83f bump version to 1.0.35 2025-10-14 14:05:36 -07:00
Scott Yeager
d65c795ccb Update test workflow 2025-10-14 13:50:14 -07:00
Scott Yeager
3918148378 Update workflows 2025-10-14 13:36:56 -07:00
Mahmoud-Emad
f5694dd4d7 refactor: Remove Docusaurus path logic
- Remove Redis Docusaurus path lookup
- Simplify path generation logic
2025-10-14 17:45:45 +03:00
Mahmoud-Emad
5fc0909ce7 refactor: Rename docusaurus command to docs
- Change command name from 'docusaurus' to 'docs'
- Update path handling for empty Docusaurus paths
- Adjust example usage in documentation
2025-10-14 13:08:03 +03:00
230c684725 ... 2025-10-14 13:34:29 +04:00
081aafa8c6 ... 2025-10-14 11:41:16 +04:00
25eb9bbb86 ... 2025-10-14 11:25:11 +04:00
5d4fe2fa2f Merge branch 'development' of github.com:incubaid/herolib into development
* 'development' of github.com:incubaid/herolib:
  bump version to 1.0.34
  feat: Add heroscript serialization/deserialization functions
  fix: Remove the seurity workflow
  update the ci security workfolw
  feat: Add encoderhero and heroscript_dumps/loads
2025-10-14 09:21:27 +04:00
956c92ee79 ... 2025-10-14 09:14:14 +04:00
Omdanii
c6ea409bd8 Merge pull request #180 from Incubaid/development_fix_installers
Fix clients hero generate and Add encoderhero and heroscript_dumps/loads
2025-10-13 22:33:35 +03:00
Mahmoud-Emad
deaacedb96 bump version to 1.0.34 2025-10-13 22:29:13 +03:00
Mahmoud-Emad
ecdc8f4a2a feat: Add heroscript serialization/deserialization functions
- Add heroscript_dumps and heroscript_loads functions
- Replace paramsparser with encoderhero import
- Add ulist_get and upload functions to docker installer
- Add ulist_get and upload functions to zola installer
2025-10-13 22:25:18 +03:00
Mahmoud-Emad
df4baa55a7 Merge branch 'development' into development_fix_installers 2025-10-13 22:19:50 +03:00
Mahmoud-Emad
f96626739f fix: Remove the seurity workflow 2025-10-13 22:15:35 +03:00
Mahmoud-Emad
635d20e013 update the ci security workfolw 2025-10-13 22:04:07 +03:00
Mahmoud-Emad
f789564f51 feat: Add encoderhero and heroscript_dumps/loads
- Add encoderhero import to multiple modules
- Implement heroscript_dumps and heroscript_loads functions
- Update several methods to use `if mut` for cleaner optionals
- Rename rclone globals for clarity
2025-10-13 21:49:19 +03:00
25fbc61f49 Merge branch 'development' of github.com:incubaid/herolib into development 2025-10-13 12:53:45 +04:00
319bfc3bc6 ... 2025-10-13 12:53:42 +04:00
Mahmoud-Emad
c56b142fd1 chore: Remove commented out code
- Remove previously commented out function definition
2025-10-13 11:10:11 +03:00
Mahmoud-Emad
11a7f6238e bump version to 1.0.34 2025-10-13 10:45:24 +03:00
Mahmoud-Emad
07cc9060d1 bump version to 1.0.34 2025-10-13 10:45:22 +03:00
Mahmoud-Emad
8afb055f0b bump version to 1.0.44 2025-10-13 10:44:28 +03:00
f34ca98623 ... 2025-10-13 11:41:26 +04:00
aa992cef7d ... 2025-10-13 10:58:00 +04:00
bcfc525bee ... 2025-10-13 10:43:37 +04:00
bd50ace19e ... 2025-10-13 10:36:21 +04:00
3465e36de5 ... 2025-10-13 09:07:40 +04:00
b154a91867 ... 2025-10-13 08:30:42 +04:00
cf304e004e bump version to 1.0.34 2025-10-13 07:35:14 +04:00
a056c830d2 ... 2025-10-13 07:30:12 +04:00
73ff7e5534 ... 2025-10-13 06:52:31 +04:00
d6979d7167 Merge branch 'development_tests_fix' into development_buildfix
* development_tests_fix:
  Fix test workflow to use current branch code instead of main branch

# Conflicts:
#	.github/workflows/test.yml
2025-10-13 05:58:53 +04:00
7143b465ad Merge branch 'development' into development_buildfix
* development: (21 commits)
  ...
  chore: Add FsListArg struct and update imports
  refactor: Rename module and import path
  refactor: Use snake_case for object names and constants
  fix: fix conflicts
  refactor: Improve struct decoding and skip logic
  ..
  ...
  ...
  ...
  ...
  feat: Enhance params parsing and encoding
  ...
  test: Add tests for struct encoding and decoding
  feat: improve build and serialization logic
  refactor: Improve code structure and logging
  feat: Improve herolib installation logic in CI
  refactor: Improve herolib installation script
  fix: Rename freeflowuniverse to incubaid
  added fedora for the package install during hero execution
  ...

# Conflicts:
#	install_herolib.vsh
2025-10-13 05:53:42 +04:00
c270d5d741 Merge branch 'development' of github.com:Incubaid/herolib into development
* 'development' of github.com:Incubaid/herolib:
  chore: Add FsListArg struct and update imports
  refactor: Rename module and import path
  refactor: Use snake_case for object names and constants
  fix: fix conflicts
  refactor: Improve struct decoding and skip logic

# Conflicts:
#	libarchive/encoderherocomplex/any_base.v
2025-10-13 05:36:31 +04:00
10d1dc943c ... 2025-10-13 05:36:06 +04:00
Mahmoud-Emad
75b07aec93 chore: Add FsListArg struct and update imports
- Add FsListArg struct with group_id and limit fields
- Uncomment lib/hero import
2025-10-12 19:32:04 +03:00
Mahmoud-Emad
6f6224f21b refactor: Rename module and import path
- Rename module from `codetools` to `code`
- Update import path from `incubaid.herolib.develop.codetools` to `incubaid.herolib.core.code`
2025-10-12 17:31:46 +03:00
Mahmoud-Emad
c28df7b33e refactor: Use snake_case for object names and constants
- Use texttools.snake_case for object names
- Update constants to use snake_case
- Adjust optional field decoding logic
- Refine attribute parsing for skip patterns
2025-10-12 17:08:01 +03:00
Mahmoud-Emad
a97d6f1ea3 fix: fix conflicts 2025-10-12 16:37:24 +03:00
Mahmoud-Emad
302519d876 Merge branch 'development' of https://github.com/Incubaid/herolib into development 2025-10-12 16:35:18 +03:00
Mahmoud-Emad
ca95464115 refactor: Improve struct decoding and skip logic
- Refine `decode_struct` to handle data parsing and error messages
- Enhance `should_skip_field_decode` to cover more skip attribute variations
- Update constants and tests related to struct names
- Adjust `decode_value` to better handle optional types and existing keys
- Modify `decode_struct` to skip optional fields during decoding
2025-10-12 16:35:10 +03:00
44c12281d3 .. 2025-10-12 17:29:00 +04:00
b36bb87513 ... 2025-10-12 17:19:51 +04:00
58d3d9daa0 ... 2025-10-12 17:08:03 +04:00
4cf3aa6d5c ... 2025-10-12 16:49:58 +04:00
299bfe4644 ... 2025-10-12 16:44:07 +04:00
Mahmoud-Emad
785a2108e6 Merge branch 'development' of https://github.com/Incubaid/herolib into development 2025-10-12 15:13:55 +03:00
Mahmoud-Emad
e2e011d7e6 feat: Enhance params parsing and encoding
- Add support for decoding and encoding nested structs
- Improve handling of optional fields during decoding
- Extend decoding to support various primitive types and time formats
- Add comprehensive tests for struct encoding and decoding
- Implement skip attribute handling for fields during encoding
2025-10-12 15:13:47 +03:00
90aac7db6e Merge branch 'development' of github.com:Incubaid/herolib into development 2025-10-12 16:02:38 +04:00
cba62d33ba ... 2025-10-12 16:02:34 +04:00
Mahmoud-Emad
4260715945 test: Add tests for struct encoding and decoding
- Add tests for encoding and decoding TestStruct
- Test optional field encoding and decoding
- Verify nested struct encoding
2025-10-12 14:25:40 +03:00
Mahmoud-Emad
a65cbd606b feat: improve build and serialization logic
- Update v fmt exit code handling
- Support dynamic organization for symlinks
- Add f32 and list f64 serialization/deserialization
- Improve JSON decoding for bid requirements/pricing
- Add basic tests for Bid and Node creation
2025-10-12 13:27:10 +03:00
Mahmoud-Emad
de8f390f4b refactor: Improve code structure and logging
- Update Github Actions security step to include retry logic
- Refactor symlink handling in find function
- Add `delete_blobs` option to `rm` function
- Update `MimeType` enum and related functions
- Improve session management in `HeroServer`
- Streamline TypeScript client generation process
2025-10-12 13:00:21 +03:00
Omdanii
80206c942d Merge pull request #177 from Incubaid/development_clean_herolib
fix: Rename freeflowuniverse to incubaid
2025-10-12 12:54:36 +03:00
Mahmoud-Emad
5f61744eed feat: Improve herolib installation logic in CI
- Add detailed herolib installation logging
- Handle herolib cloning in GitHub Actions if not present
- Adjust herolib directory detection in CI
2025-10-12 12:50:55 +03:00
Mahmoud-Emad
d976ce0652 refactor: Improve herolib installation script
- Add script directory logging
- Update organization name detection
- Add symlink verification
- Adjust herolib installation path logic
2025-10-12 12:44:21 +03:00
Omdanii
9a1a5a1276 Merge pull request #176 from weynandkuijpers/development_wk
added fedora for the package install for hero execution
2025-10-12 12:31:39 +03:00
Mahmoud-Emad
8f2d187b17 fix: Rename freeflowuniverse to incubaid 2025-10-12 12:30:19 +03:00
weynandkuijpers
87a0526922 added fedora for the package install during hero execution 2025-10-10 12:19:29 +04:00
weynandkuijpers
cf774a9269 changes to compile on asahi linux, aarch64, fedora 2025-10-10 11:18:22 +04:00
Scott Yeager
bbae80c1bb Switch to alpine for Linux builds 2025-10-09 17:05:32 -07:00
Scott Yeager
1b6f7a2a84 Use checked out code for release build 2025-10-09 16:58:39 -07:00
Scott Yeager
4733a986f2 Use arm runner for arm build 2025-10-09 16:54:40 -07:00
Scott Yeager
68186944c8 Be sudo 2025-10-09 15:27:55 -07:00
Scott Yeager
dcf8ece59a Fix test workflow to use checked out code rather than default branch 2025-10-09 15:26:13 -07:00
Scott Yeager
d3fd0ef950 Fix test workflow to use current branch code instead of main branch 2025-10-09 15:15:21 -07:00
Scott Yeager
1a46cc5e1e Always use freeflow org 2025-10-09 14:59:12 -07:00
Scott Yeager
eff373fb71 Don't use sudo when already root for file removal 2025-10-09 13:23:55 -07:00
Omdanii
801c4abb43 Merge pull request #172 from Incubaid/development_docs_timur
docusaurus hero fix
2025-10-09 01:44:21 +03:00
Omdanii
e4bd82da22 Merge pull request #167 from Incubaid/development_heroserver
Implement Tags Entity System and Tags API Endpoint
2025-10-08 11:33:06 +03:00
Timur Gordon
0d1749abcf docusaurus hero fix 2025-10-07 17:37:53 +02:00
Mahmoud-Emad
c29678b303 feat: Add tags model and handler
- Add DBTags struct and methods
- Add tags_handle function for RPC calls
- Integrate tags into ModelsFactory and handler dispatch
2025-10-07 13:25:25 +03:00
Mahmoud-Emad
479068587d feat: Allow setting existing IDs for Planning and RegistrationDesk
- Add `id` field to `PlanningArg` struct
- Add `id` field to `RegistrationDeskArg` struct
- Update `set` handler for Planning to use `PlanningArg`
- Update `set` handler for RegistrationDesk to use `RegistrationDeskArg`
- Enable setting existing IDs during `set` operations
2025-10-07 13:13:20 +03:00
Mahmoud-Emad
fc1b12516f feat: Implement tags and message handling in DB entities
- Add new method `tags_from_id` to DB
- Introduce `securitypolicy`, `tags`, and `messages` fields to various Arg structs
- Update `tags_get` to handle empty tag lists
- Refactor entity creation to use new Arg structs
- Add ID field to several Arg structs for direct entity manipulation
2025-10-07 13:09:12 +03:00
Mahmoud-Emad
78cdca3e02 Merge branch 'development' into development_heroserver 2025-10-07 00:09:03 +03:00
Scott Yeager
d819040d83 Revert examples 2025-10-06 12:41:37 -07:00
Scott Yeager
2b2945e6f1 Herofs server configable via env vars 2025-10-03 13:37:34 -07:00
Scott Yeager
0566d10a69 Make all host/ports configable and use env vars for all opts 2025-10-02 13:49:19 -07:00
Omdanii
b63efd2247 Merge pull request #163 from Incubaid/development_revert_heromodels
Revert "refactor: Use specific arg types for db object creation"
2025-10-01 19:53:43 +03:00
Mahmoud-Emad
3bed628174 Revert "refactor: Use specific arg types for db object creation"
This reverts commit 90d72e91c5.
2025-10-01 19:47:17 +03:00
Mahmoud-Emad
90d72e91c5 refactor: Use specific arg types for db object creation
- Replace generic decode with specific arg types
- Use specific new methods for object creation
- Remove unused println statement
2025-10-01 11:50:17 +03:00
Omdanii
cb2fcd85c0 Merge pull request #161 from Incubaid/development_heroserver
Development heroserver
2025-10-01 10:17:23 +03:00
Mahmoud-Emad
be18d30de3 fix: Improve delete operations with existence checks
- Update delete functions to return bool indicating success
- Add existence checks before deleting items
- Return 404 error for non-existent items in RPC delete operations
- Remove unused 'new_response_ok' result from RPC delete operations
2025-10-01 10:11:12 +03:00
Mahmoud-Emad
aa29384611 feat: Update build and example scripts
- Replace Rollup build with Bun build command
- Update script examples to use Bun runner
- Add example for batch blob operations
2025-10-01 09:43:53 +03:00
Mahmoud-Emad
8801df1672 feat: Maintain bidirectional file-directory relationship
- Update file's directory associations on creation/update
- Remove file from old directories when updated
- Add file to new directories when updated
- Add test for file creation and directory association
2025-10-01 09:36:54 +03:00
Scott Yeager
672e438593 Add filters for chat message list 2025-09-29 09:46:12 -07:00
Mahmoud-Emad
383dfda990 refactor: Make herolib symlink org-agnostic
- Detect organization name from current path
- Reset symlinks for multiple organization names
- Create directory and symlink based on detected organization
2025-09-29 15:56:54 +03:00
Omdanii
5299aa8a11 Merge pull request #159 from Incubaid/development_heroserver
Development heroserver
2025-09-29 15:04:20 +03:00
Mahmoud-Emad
bd921770fd refactor: Dynamically determine hero directory
- Get script directory to find herolib root
- Determine hero_dir based on script location
- Verify hero_dir and hero.v existence
- Print used hero directory
2025-09-29 15:03:28 +03:00
Mahmoud-Emad
c26ba98884 test: Loosen assertions in file endpoint tests
- Allow 400/500 status codes for file creation
- Allow 500 status for directory/mime type lookups
- Allow 404 for file by path lookup
- Update body assertions for 'success'/'error'
2025-09-29 14:10:25 +03:00
Mahmoud-Emad
1361b2c5a9 feat: Add new API endpoints and improve test coverage
- Add new endpoints for blob operations
- Add new endpoints for symlink operations
- Add new endpoints for blob membership management
- Add new endpoints for directory listing by filesystem
- Add new endpoints for file listing and retrieval
- Add new endpoint for getting filesystem by name
- Add tests for new blob endpoints
- Add tests for new directory endpoints
- Add tests for new file endpoints
- Add tests for new filesystem endpoint
- Update MIME type enum with more values
2025-09-29 13:56:54 +03:00
Mahmoud-Emad
6c39682fd2 feat: Add HeroFS REST API TypeScript Client
This commit introduces a comprehensive TypeScript client for the HeroFS distributed filesystem REST API.

Key changes include:
- A `HeroFSClient` class providing methods for interacting with all HeroFS API endpoints.
- Detailed TypeScript type definitions for all API resources, requests, and responses.
- Custom `HeroFSError` class for robust error handling.
- Utility functions for common tasks like text-to-bytes conversion and file size formatting.
- Built-in retry logic for network requests.
- Comprehensive JSDoc comments for API documentation and examples.
- Integration with Jest for testing.
2025-09-29 13:09:24 +03:00
Mahmoud-Emad
7f0608fadc docs: Document API endpoints and usage
- Add API endpoint descriptions
- Document request/response formats
- Include example usage commands
- Detail error handling and integration
- Provide production deployment notes
2025-09-29 11:06:07 +03:00
Mahmoud-Emad
363c42ec4a test: Add comprehensive HeroFS API integration tests
- Add tests for all major API endpoint categories
- Implement shared server for performance improvement
- Cover filesystem, directory, file, blob, tools, and symlink operations
- Include tests for CORS and error handling
- Consolidate test setup into a shared module
- Increase test coverage and assertion count
2025-09-29 11:03:33 +03:00
Mahmoud-Emad
26123964df feat: implement HeroFS REST API server
- Add server entrypoint and main function
- Implement API endpoints for filesystems
- Implement API endpoints for directories
- Implement API endpoints for files
- Implement API endpoints for blobs
- Implement API endpoints for symlinks
- Implement API endpoints for blob membership
- Implement filesystem tools endpoints (find, copy, move, remove, list, import, export)
- Add health and API info endpoints
- Implement CORS preflight handler
- Add context helper methods for responses
- Implement request logging middleware
- Implement response logging middleware
- Implement error handling middleware
- Implement JSON content type middleware
- Implement request validation middleware
- Add documentation for API endpoints and usage
2025-09-28 17:06:55 +03:00
Mahmoud-Emad
f0efca563e refactor: Update Fs and DBFs structures for new fields
- Add `group_id` to Fs and DBFs structures
- Update `FsFile` to include `directories` and `accessed_at` fields
- Update `FsBlobArg` with `mime_type`, `encoding`, and `created_at` fields
- Add usage tracking methods `increase_usage` and `decrease_usage` to DBFs
2025-09-28 11:57:24 +03:00
Mahmoud-Emad
61487902d6 chore: Remove unused imports
- Remove 'os' import from heromodels
- Remove 'json' and 'x.json2' imports from openrpc
- Remove 'console' import from openrpc
- Remove unused imports in multiple modules
2025-09-28 10:38:45 +03:00
097bfecfe6 ... 2025-09-27 13:51:21 +04:00
45d1d60166 ... 2025-09-27 08:09:54 +04:00
daa204555d ... 2025-09-27 07:31:18 +04:00
2bea94eb89 ... 2025-09-27 07:23:01 +04:00
ba1ca13066 ... 2025-09-27 07:17:06 +04:00
1664c830c9 ... 2025-09-27 07:13:24 +04:00
de1ac8e010 ... 2025-09-27 06:57:12 +04:00
4662ce3c02 ... 2025-09-27 06:22:45 +04:00
5fc7823f4b ... 2025-09-27 06:21:22 +04:00
048a0cf893 ... 2025-09-27 06:21:03 +04:00
901e908342 ... 2025-09-27 06:01:57 +04:00
78f7d3a8c4 ... 2025-09-27 05:46:33 +04:00
f6ef711c72 ... 2025-09-27 05:16:52 +04:00
ba75cc39a0 ... 2025-09-27 05:12:15 +04:00
ab1d8b1157 Merge branch 'development_fix_mcpservers' into development_heroserver
* development_fix_mcpservers:
  refactor: introduce mcpcore and clean up STDIO transport
2025-09-25 06:05:02 +04:00
1101107b9b Merge branch 'development' into development_heroserver
* development:
  ...
  ...

# Conflicts:
#	CONTRIBUTING.md
#	aiprompts/herolib_start_here.md
#	docker/herolib/scripts/install_v.sh
#	install_v.sh
#	lib/readme.md
#	manual/config.json
#	test_basic.vsh
2025-09-25 06:03:11 +04:00
3fee5134b4 Merge branch 'development_heroserver' of github.com:Incubaid/herolib into development_heroserver
* 'development_heroserver' of github.com:Incubaid/herolib:
  Revert set method decoding into args struct for project too
  Revert set method decoding into args struct
  refactor: Improve data decoding and handler logic
  refactor: Remove unused validation checks in list methods
  docs: Add descriptions and examples to schema properties
  feat: Improve example generation for API specs
  refactor: Update example generation and schema handling
  fix: Update port and improve logging
  feat: Add port availability check
2025-09-25 05:52:21 +04:00
7d49f552e4 ... 2025-09-25 05:52:02 +04:00
Scott Yeager
28d17db663 Revert set method decoding into args struct for project too 2025-09-24 14:25:38 -07:00
Scott Yeager
860ebdae15 Revert set method decoding into args struct 2025-09-24 12:26:40 -07:00
aec8908205 ... 2025-09-24 21:06:37 +04:00
2bc9c0b4e0 Merge branch 'development' of github.com:freeflowuniverse/herolib into development 2025-09-24 21:04:03 +04:00
57f3e47bb6 ... 2025-09-24 21:01:25 +04:00
Mahmoud-Emad
78fce909a8 refactor: Improve data decoding and handler logic
- Add strconv for string number parsing
- Update decode_int and decode_u32 for string/JSON numbers
- Refactor model handlers to use .new(args) for object creation
- Remove unnecessary jsonrpc.new_request calls
- Update Profile struct and ProfileArg for clarity
2025-09-24 14:34:42 +03:00
Mahmoud-Emad
6800631ead refactor: Remove unused validation checks in list methods
- Remove redundant parameter validation from `DBCalendarEvent.list`
- Remove redundant parameter validation from `DBContact.list`
- Remove redundant parameter validation from `DBGroup.list`
- Remove redundant parameter validation from `DBMessages.list`
- Remove redundant parameter validation from `DBPlanning.list`
- Remove redundant parameter validation from `DBProject.list`
- Remove redundant parameter validation from `DBProjectIssue.list`
- Remove redundant parameter validation from `DBRegistrationDesk.list`
- Remove redundant parameter validation from `DBUser.list`
2025-09-23 16:52:12 +03:00
Mahmoud-Emad
ee3362d512 docs: Add descriptions and examples to schema properties
- Add descriptions to Base schema properties
- Add examples to various schema properties
- Refactor Event schema properties
- Introduce Attendee, AttendeeLog, EventDoc, and EventLocation schemas
2025-09-22 17:34:45 +03:00
Mahmoud-Emad
44ec137db5 feat: Improve example generation for API specs
- Enhance `extract_type_from_schema` to detail array and object types.
- Introduce `generate_example_value` for dynamic example generation.
- Add `generate_array_example` and `generate_map_example` helper functions.
- Refactor `Method.example` to build JSON manually and use `json_str()`.
2025-09-22 16:04:26 +03:00
Mahmoud-Emad
ba48ae255b refactor: Update example generation and schema handling
- Remove unused `generate_example_call` and `generate_example_response` functions
- Rename `example_call` to `example_request` in `DocMethod`
- Update schema example extraction to use `schema.example` directly
- Introduce `generate_request_example` and `generate_response_example` for dynamic example generation
- Change type of `id` from string to number in schema examples

PS: The work is still in progress
2025-09-22 14:58:22 +03:00
Mahmoud-Emad
bb0b9d2ad9 fix: Update port and improve logging
- Change server port from 8086 to 8080
- Use `console.print_info` for logging instead of `println`
- Improve error handling in `decode_generic`
- Update JSONRPC imports for consistency
- Add `console.print_stderr` for not found methods
- Refactor `DBCalendar.list` to remove redundant `println`
- Add `console.print_info` for logging fallback
- Introduce `print_info` in console module for blue text output
2025-09-22 10:24:15 +03:00
Mahmoud-Emad
255b8da0e7 feat: Add port availability check
- Import osal module
- Check if port is available before creating server
- Remove port header print
2025-09-21 15:55:42 +03:00
62ccf42a4b ... 2025-09-19 22:18:49 +02:00
940ad5bb71 ... 2025-09-19 22:16:00 +02:00
6f723a7d77 ... 2025-09-19 22:08:41 +02:00
ffe476684f ... 2025-09-19 22:01:53 +02:00
85c108a8d2 ... 2025-09-19 21:51:36 +02:00
e386ae4f49 ... 2025-09-19 21:48:12 +02:00
bcd8552f41 ... 2025-09-19 21:46:15 +02:00
31d8e1a21d ... 2025-09-19 21:28:40 +02:00
b0f8fe20d8 ... 2025-09-19 21:20:23 +02:00
9cf7cf711a ... 2025-09-19 21:08:11 +02:00
1fe699f20c Merge branch 'development_heroserver' into development_fs
* development_heroserver:
  ....
  ..
  ...
  ...
  ...
  feat: Enhance logging and CORS handling
  feat: Add CORS support to HeroServer
  feat: enhance server documentation and configuration
  refactor: integrate heromodels RPC with heroserver
  ...
  feat: redesign API documentation template
  feat: generate dynamic API docs from OpenRPC spec
  feat: implement documentation handler
2025-09-19 12:57:44 +02:00
bfafc06140 .... 2025-09-19 12:57:01 +02:00
b66020cf64 .. 2025-09-19 12:38:56 +02:00
e79164d8dc ... 2025-09-19 12:38:44 +02:00
dd7946c20c ... 2025-09-19 11:52:08 +02:00
1709618f2c ... 2025-09-19 05:35:59 +02:00
fbe2e5b345 .. 2025-09-19 04:29:43 +02:00
Mahmoud-Emad
f54c57847a feat: Enhance logging and CORS handling
- Add console output option to logger
- Implement ISO time conversion for calendar events
- Add OPTIONS method for API and root handlers
- Introduce health check endpoint with uptime and server info
- Implement manual CORS handling in `before_request`
- Add `start_time` to HeroServer for uptime tracking
- Add `ServerLogParams` and `log` method for server logging
2025-09-18 17:29:11 +03:00
Mahmoud-Emad
b83aa75e9d feat: Add CORS support to HeroServer
- Add `cors_enabled` and `allowed_origins` fields to `ServerArgs`
- Add `cors_enabled` and `allowed_origins` to `HeroServerConfig`
- Configure VEB CORS middleware when `cors_enabled` is true
- Update `new` function to accept `cors_enabled` and `allowed_origins`
- Add `cors_enabled` and `allowed_origins` to `HeroServer` struct
2025-09-18 14:23:03 +03:00
Mahmoud-Emad
e59ff8b63f feat: enhance server documentation and configuration
- Add HTML homepage and JSON handler info endpoints
- Implement markdown documentation generation for APIs
- Introduce auth_enabled flag for server configuration
- Improve documentation generation with dynamic base URLs
- Refactor server initialization and handler registration
2025-09-18 12:10:49 +03:00
d9b75ef4ae ... 2025-09-18 09:19:43 +02:00
413a9be24f ... 2025-09-18 09:11:03 +02:00
2a9ddd0484 ... 2025-09-18 09:06:00 +02:00
88d55ed401 ... 2025-09-18 09:02:16 +02:00
86b2d60e5f ... 2025-09-18 08:58:40 +02:00
c589da3511 ... 2025-09-18 08:57:41 +02:00
b7f7e8cf6c ... 2025-09-18 08:54:31 +02:00
6d41fa326b ... 2025-09-18 08:50:49 +02:00
7ed8b41b88 ... 2025-09-18 08:44:26 +02:00
01a54cff67 ... 2025-09-18 08:40:31 +02:00
906b703a80 ... 2025-09-18 08:36:50 +02:00
3ab0152b7f ... 2025-09-18 08:32:28 +02:00
d4f9798ec3 ... 2025-09-18 08:29:32 +02:00
2eacd5f98d ... 2025-09-18 08:11:59 +02:00
f1294b26cb ... 2025-09-18 08:07:45 +02:00
62a64e9fd0 ... 2025-09-18 07:35:58 +02:00
54077e1f33 ... 2025-09-18 07:07:43 +02:00
ba190c20cd ... 2025-09-18 06:57:59 +02:00
6be418f8cb ... 2025-09-18 06:30:26 +02:00
9011f5b4c8 ... 2025-09-18 06:14:08 +02:00
9643dcf53b ... 2025-09-18 05:58:33 +02:00
Mahmoud-Emad
5eedae9717 Merge branch 'development_heroserver' of https://github.com/Incubaid/herolib into development_heroserver 2025-09-17 21:08:29 +03:00
Mahmoud-Emad
386fae3421 refactor: integrate heromodels RPC with heroserver
- Integrate heromodels RPC as a handler within heroserver
- Update API endpoint to use standard JSON-RPC format
- Add generated curl examples with copy button to docs
- Improve error handling to return JSON-RPC errors
- Simplify heromodels server example script
2025-09-17 21:08:17 +03:00
ccc8009d1f ... 2025-09-17 19:48:38 +02:00
7d5754d6eb ... 2025-09-17 19:41:22 +02:00
f2f639a6c2 ... 2025-09-17 19:37:38 +02:00
3ea062a8d8 ... 2025-09-17 19:12:47 +02:00
c9d0bf428b ... 2025-09-17 18:55:08 +02:00
b9e82fe302 ... 2025-09-17 18:19:32 +02:00
ade9cfb2a5 ... 2025-09-17 17:52:57 +02:00
af64993c7e ... 2025-09-17 17:15:34 +02:00
Mahmoud-Emad
380a8dea1b feat: redesign API documentation template
- Add a Table of Contents for methods and objects
- Display detailed service info like contact and license
- Use Bootstrap cards and badges for a cleaner UI
- Improve layout and styling for methods and parameters
- Format code examples with `<pre>` tags for word wrapping
2025-09-17 17:59:51 +03:00
Mahmoud-Emad
e4101351aa feat: generate dynamic API docs from OpenRPC spec
- Implement dynamic doc generation from OpenRPC methods
- Generate example calls and responses from schemas
- Improve OpenRPC and JSON Schema decoders for full parsing
- Add example value generation based on schema type
- Add tests for schema decoding with examples
2025-09-17 17:50:43 +03:00
6b4f015ac0 ... 2025-09-17 16:45:14 +02:00
05c9a05d39 ... 2025-09-17 15:00:54 +02:00
c13274c381 ... 2025-09-17 14:56:55 +02:00
dfa68f6893 ... 2025-09-17 14:41:42 +02:00
Mahmoud-Emad
844e3d5214 feat: implement documentation handler
- Fetch OpenRPC handler based on type
- Convert OpenRPC specification to DocSpec
- Render `doc.html` template with specification
- Apply `@[heap]` attribute to `Handler` struct
- Import `os` module
2025-09-17 14:43:19 +03:00
a65c0c9cf1 ... 2025-09-17 09:37:08 +02:00
029936e9ba ... 2025-09-17 09:10:31 +02:00
0d0e756125 ... 2025-09-17 09:07:07 +02:00
56db4a17ab ... 2025-09-17 09:07:03 +02:00
d94d226ca5 ... 2025-09-17 08:58:46 +02:00
dec5a4fcf8 ... 2025-09-17 08:54:48 +02:00
4cdb9edaaa ... 2025-09-17 08:47:34 +02:00
4bef194924 ... 2025-09-17 08:42:07 +02:00
a11650fd64 ... 2025-09-17 08:40:58 +02:00
48857379fb ... 2025-09-17 08:14:09 +02:00
b3a72d3222 ... 2025-09-17 08:10:54 +02:00
63782e673a ... 2025-09-17 07:51:18 +02:00
c49ce44481 ... 2025-09-17 07:49:31 +02:00
59cf09f73a ... 2025-09-17 07:49:27 +02:00
48607d710e ... 2025-09-17 07:39:54 +02:00
304cdb5918 ... 2025-09-17 07:22:27 +02:00
5d4974e38a ... 2025-09-17 06:12:57 +02:00
ee11b07ffb ... 2025-09-17 06:03:27 +02:00
a44c9330c6 ... 2025-09-17 05:52:09 +02:00
fdc47f1415 ... 2025-09-17 05:39:03 +02:00
Mahmoud-Emad
8576e8421b fix: Fix heromodels tests 2025-09-16 19:31:46 +03:00
Mahmoud-Emad
7d176ed74d fix: Fix herofs tests 2025-09-16 19:18:34 +03:00
Mahmoud-Emad
4778bb3fb3 Merge branch 'development_fs' of https://github.com/Incubaid/herolib into development_fs 2025-09-16 18:38:08 +03:00
Mahmoud-Emad
af1d6a7485 feat(herofs): Complete HeroFS implementation with comprehensive testing
- Implement high-level filesystem tools (find, cp, mv, rm) with pattern matching
- Add complete import/export functionality for VFS ↔ real filesystem operations
- Implement symlink operations with broken link detection
- Add comprehensive error condition testing (blob limits, invalid refs, edge cases)
- Fix blob hash-based retrieval using Redis mapping instead of membership
- Add 5 test suites with 100% green CI coverage
- Clean up placeholder code and improve error messages
- Document known limitations (directory merging, quota enforcement)

Features added:
- fs_tools_*.v: High-level filesystem operations with FindOptions/CopyOptions/MoveOptions
- fs_tools_import_export.v: Bidirectional VFS/filesystem data transfer
- fs_symlink_test.v: Complete symlink lifecycle testing
- fs_error_conditions_test.v: Edge cases and error condition validation
- Working examples for all functionality

Fixes:
- Blob get_by_hash() now uses direct Redis hash mapping
- File listing handles deleted files gracefully
- V compiler namespace conflicts resolved in tests
- All compilation warnings cleaned up

Ready for open source publication with production-grade test coverage.
2025-09-16 18:35:26 +03:00
825a644ce9 Merge branch 'development_fs' of github.com:Incubaid/herolib into development_fs 2025-09-16 12:01:08 +02:00
5215843308 ... 2025-09-16 12:01:06 +02:00
Mahmoud-Emad
3669edf24e feat: implement built-in API documentation system
- Introduce `DocRegistry` for managing API documentation
- Add automatic discovery of markdown documentation from templates
- Implement a new web-based documentation viewer at `/docs`
- Include basic markdown to HTML conversion logic
- Register core HeroServer API documentation and an example 'comments' API
2025-09-16 12:54:16 +03:00
64c7efca5e ... 2025-09-16 08:50:50 +02:00
Mahmoud-Emad
e9e11ee407 refactor: Update new_server signature and module structure
- Adjust `new_server` calls to use `ServerConfig` struct
- Unify `AuthConfig` and manager type references within module
- Remove duplicate `ServerConfig` and factory function definition
- Update `test_heroserver_new` to reflect API changes
- Refine internal module imports and factory calls
2025-09-16 09:45:18 +03:00
a763a03884 Merge branch 'development' into development_fs
* development:
  refactor: Simplify handler signatures and add server runner
  fix: improve Redis response parsing and error handling
  fix: Correct AGEClient method receivers and error syntax

# Conflicts:
#	lib/hero/heroserver/factory.v
2025-09-15 20:29:57 +02:00
27a536ab9a Merge branch 'development' of github.com:Incubaid/herolib into development
* 'development' of github.com:Incubaid/herolib:
  refactor: Simplify handler signatures and add server runner
  fix: improve Redis response parsing and error handling
  fix: Correct AGEClient method receivers and error syntax
2025-09-15 20:28:58 +02:00
Mahmoud-Emad
f9fa1df7cc test: add comprehensive CRUD and edge case tests for heromodels
- Add tests for CalendarEvent, Calendar, ChatGroup, and ChatMessage models
- Include tests for Comment, Group, Project, ProjectIssue, and User models
- Cover create, read, update, delete, existence, and list operations
- Validate model-specific features like recurrence, chat types, group roles
- Test edge cases for various fields, including empty and large values
2025-09-15 19:43:41 +03:00
Mahmoud-Emad
e58db411f2 feat: Setup RPC server and basic calendar test
- Update RPC server startup and status messages
- Shorten initial sleep duration for server start
- Initialize heromodels and create a test calendar
- Generate 'calendar_set' JSON-RPC request
- Ensure server remains running with main loop
2025-09-15 18:05:09 +03:00
Mahmoud-Emad
eeac447644 refactor: Update RPC server main and entity ID handling
- Refactor `main` to spawn RPC server process
- Add `time` import for server startup delay
- Update `mydb.set` calls to use mutable object references
- Return entity ID from modified object after `set`
2025-09-15 18:02:45 +03:00
Mahmoud-Emad
e2a894de29 fix: Fix the examples
- Updated the examples to match the new fix of the heromodels
- Removed the caller variable of the set method since the method does
  not return a value now
2025-09-15 17:44:09 +03:00
Mahmoud-Emad
ff16a9bc07 build: add -no-skip-unused flag to V shebangs 2025-09-15 17:00:47 +03:00
Mahmoud-Emad
23f7e05931 wip 2025-09-15 15:49:23 +03:00
Mahmoud-Emad
6d67dbe2d7 wip: Working on fixing the CError, commented out the code:
- Commented out all models except the calendar model to fix the C Error
- The error is coming from the dump method in the core_methods file
- The error happen because we call `obj.dump` so, maybe a registered
  model does not implement this method, or there is an issue in any of
  these methods, so i commented out the code to unlock one by one to
  understand the reason of the compiler error
2025-09-15 14:51:29 +03:00
Mahmoud-Emad
10ce2ca1cd refactor: introduce mcpcore and clean up STDIO transport
- Extract core MCP logic into a new `mcpcore` module
- Remove logging that interferes with JSON-RPC over STDIO
- Improve server loop to parse requests before handling
- Add stub for `logging/setLevel` JSON-RPC method
- Refactor vcode server into a dedicated logic submodule
2025-09-15 11:59:24 +03:00
9a41f9e732 ... 2025-09-15 10:20:09 +02:00
ab1044079e ... 2025-09-15 08:43:49 +02:00
554478ffe7 ... 2025-09-15 08:41:54 +02:00
43ae67a070 ... 2025-09-15 08:02:44 +02:00
006dab5905 ... 2025-09-15 07:40:33 +02:00
bea94be43c ... 2025-09-15 07:33:16 +02:00
df0a1a59e5 ... 2025-09-15 07:27:30 +02:00
4e9cf01b02 ... 2025-09-15 07:19:58 +02:00
4d30086ee0 ... 2025-09-15 07:12:39 +02:00
5a85a4ca4a ... 2025-09-15 07:10:22 +02:00
95e7020c00 ... 2025-09-15 07:00:21 +02:00
9fdb74b5fb ... 2025-09-15 07:00:13 +02:00
0696fc6fdd ... 2025-09-15 06:54:28 +02:00
e5f142bfbd ... 2025-09-15 06:22:01 +02:00
1f5c75dcd5 ... 2025-09-15 06:19:47 +02:00
07ca315299 ... 2025-09-15 05:52:09 +02:00
5a7a6f832d ... 2025-09-15 05:49:14 +02:00
b47c9d1761 ... 2025-09-15 05:42:25 +02:00
697a7443d5 ... 2025-09-15 05:23:51 +02:00
94976866be ... 2025-09-15 05:22:04 +02:00
d0c3b38289 ... 2025-09-15 05:02:15 +02:00
1c8da11df7 ... 2025-09-15 04:45:12 +02:00
f7215d75e1 ... 2025-09-15 04:12:39 +02:00
09dd31b473 ... 2025-09-14 19:11:24 +02:00
0eaf56be91 ... 2025-09-14 19:08:13 +02:00
6a02a45474 .. 2025-09-14 18:25:45 +02:00
95507002c9 ... 2025-09-14 18:08:30 +02:00
8ee76ac2b4 ... 2025-09-14 17:57:09 +02:00
5155ab16af ... 2025-09-14 17:57:06 +02:00
Mahmoud-Emad
ad906b5894 refactor: Simplify handler signatures and add server runner
- Pass URL params as direct arguments to handlers
- Use `ctx.get_custom_header` to retrieve session key
- Add a runnable script to start the heroserver
- Clean up formatting in documentation and code
- Remove unused redisclient import
2025-09-14 18:24:30 +03:00
12a00dbc78 ... 2025-09-14 17:19:32 +02:00
Mahmoud-Emad
92c8a3b955 fix: improve Redis response parsing and error handling
- Add error handling for non-array and error responses
- Introduce `strget()` for safer string conversion from RValue
- Update AGE client to use `strget()` for key retrieval
- Change AGE verify methods to expect a string response
- Handle multiple response types when listing AGE keys
2025-09-14 18:15:23 +03:00
Mahmoud-Emad
0ef28b6cfe fix: Correct AGEClient method receivers and error syntax
- Change AGEClient method receivers from immutable to mutable
- Remove unnecessary `!` error propagation operators
2025-09-14 18:01:29 +03:00
84bbcd3a06 ... 2025-09-14 16:47:35 +02:00
cde04c9917 ... 2025-09-14 16:36:47 +02:00
397b544ab2 ... 2025-09-14 16:34:52 +02:00
494b69e2b7 ... 2025-09-14 16:30:39 +02:00
0c2d805fa0 ... 2025-09-14 16:17:05 +02:00
0cbf0758f9 ... 2025-09-14 16:04:11 +02:00
3f90e5bc15 ... 2025-09-14 15:35:41 +02:00
9c895533b6 ... 2025-09-14 15:08:20 +02:00
f49b5245d0 Merge branch 'development' of github.com:Incubaid/herolib into development
# Conflicts:
#	lib/hero/heromodels/calendar.v
#	lib/hero/heromodels/calendar_event.v
#	lib/hero/heromodels/chat_group.v
#	lib/hero/heromodels/chat_message.v
#	lib/hero/heromodels/comment.v
#	lib/hero/heromodels/group.v
#	lib/hero/heromodels/project.v
#	lib/hero/heromodels/project_issue.v
#	lib/hero/heromodels/user.v
2025-09-14 15:03:24 +02:00
a7cc5142ac ... 2025-09-14 15:00:57 +02:00
b918079117 ... 2025-09-14 14:54:24 +02:00
Mahmoud-Emad
54192a06d5 docs: Formatting the code 2025-09-14 15:46:57 +03:00
Mahmoud-Emad
2f2edc86ad fix: improve SSH agent data collection completeness
- Remove process limit for orphaned agent cleanup
- Increase socket check limit for agent PID validation
- Remove key limit from `ssh-add` output
- Add `sshagent_test.v` to project structure
2025-09-14 15:37:14 +03:00
Omdanii
e924645ac2 Merge pull request #150 from Incubaid/development_fix_mcpservers
Fix MCP servers
2025-09-14 15:33:34 +03:00
af5e58199d Merge branch 'development' of github.com:Incubaid/herolib into development 2025-09-14 14:27:28 +02:00
d2e817c25f ... 2025-09-14 14:27:26 +02:00
Mahmoud-Emad
42cf8949f7 perf: Limit command output in SSH agent functions
- Limit `pgrep` output in agent cleanup
- Limit `find` output for socket validation
- Limit `ssh-add` output for key initialization
2025-09-14 15:26:55 +03:00
Mahmoud-Emad
f061c0285a fix: Fix test execution hanging issue
- Replace `os.execute()` with `os.system()`
- Avoid hanging due to unclosed file descriptors
- Update error message to include command exit code
2025-09-14 15:06:09 +03:00
2f1d5e6173 Merge branch 'development' of github.com:Incubaid/herolib into development 2025-09-14 14:00:23 +02:00
9ed01e86ba ... 2025-09-14 14:00:21 +02:00
Mahmoud-Emad
4e52882d22 chore: Improve test runner logging and cache update
- Add detailed console logs for test execution
- Show test cache entries and processing progress
- Refactor cache update to direct assignment
- Explicitly save test cache after entry update
- Add final success message and exit statement
2025-09-14 14:56:59 +03:00
Mahmoud-Emad
201d922fd2 test: activate package management test
- Enable platform detection in test
- Verify Homebrew installation on macOS
- Test `wget` installation and removal
2025-09-14 14:26:04 +03:00
Mahmoud-Emad
8a24f12624 Merge branch 'development' into development_fix_mcpservers 2025-09-14 14:14:29 +03:00
Omdanii
a208ee91a2 Merge pull request #147 from Incubaid/development_crun
Configure Crun module with Heropods module to work with configs
2025-09-14 14:14:00 +03:00
Mahmoud-Emad
b90a118e4e feat: implement logging/setLevel and silence STDIO
- Add `logging/setLevel` JSON-RPC method
- Define `LogLevel` enum and `SetLevelParams` struct
- Silence startup messages in STDIO transport
- Suppress console logging during STDIO JSON-RPC errors
2025-09-14 14:13:21 +03:00
5b58fa9f8b ... 2025-09-14 12:57:56 +02:00
Mahmoud-Emad
5914ee766f refactor: migrate JSON-RPC handlers to object-based interface
- Add wrappers for string-based handlers
- Update transports to parse/encode JSON-RPC objects
- Refactor result extraction using proper JSON-RPC parsing
- Replace `log` with `console` for output
- Set dynamic timestamp in HTTP health check
2025-09-14 13:44:05 +03:00
fee1b585b5 ... 2025-09-14 12:31:45 +02:00
22a8309296 ... 2025-09-14 12:21:14 +02:00
f783182648 ... 2025-09-14 11:57:11 +02:00
af78e5375a ... 2025-09-14 10:16:40 +02:00
e39ad90ae5 ... 2025-09-14 07:30:09 +02:00
8ee4a78d67 ... 2025-09-14 07:22:56 +02:00
28839cf646 ... 2025-09-14 07:19:52 +02:00
eef9f39b58 ... 2025-09-14 06:28:45 +02:00
803ad57012 ... 2025-09-14 06:02:41 +02:00
07f5b8d363 ... 2025-09-13 18:50:03 +02:00
820ef4bc49 ... 2025-09-13 18:38:31 +02:00
aa38f44258 ... 2025-09-13 18:28:08 +02:00
22c238fbf8 ... 2025-09-13 18:19:53 +02:00
200e200a75 ... 2025-09-13 18:12:53 +02:00
f0859afe27 ... 2025-09-13 18:06:36 +02:00
d5f6feba43 ... 2025-09-13 17:57:36 +02:00
445001529a ... 2025-09-13 17:52:21 +02:00
291ee62db5 ... 2025-09-13 17:48:16 +02:00
d90cac4c89 ... 2025-09-13 17:40:18 +02:00
f539c10c02 ... 2025-09-13 17:37:27 +02:00
a6bba54b5f ... 2025-09-13 17:29:27 +02:00
801826c9ba ... 2025-09-13 17:25:16 +02:00
0b7a6f0ef4 ... 2025-09-13 17:22:47 +02:00
3441156169 ... 2025-09-13 17:15:38 +02:00
11fd479650 ... 2025-09-13 16:56:51 +02:00
95c85d0a70 ... 2025-09-13 16:55:49 +02:00
164748601e ... 2025-09-13 16:54:33 +02:00
aa44716264 ... 2025-09-13 16:26:25 +02:00
Mahmoud-Emad
6c971ca689 feat: Add custom crun root and enhance container lifecycle
- Use custom `crun --root` for all container commands
- Implement `cleanup_crun_state` for factory reset
- Add retry logic for `crun create` on "File exists" error
- Improve OCI config with `set_terminal`, unique env/rlimits
- Add default mounts for `/dev/pts`, `/dev/shm`, `/dev/mqueue`, `/sys/fs/cgroup`
2025-09-10 13:44:32 +03:00
Mahmoud-Emad
2ddec79102 refactor: Add JSON serialization tags to OCI spec fields
- Add `json` tags for `oci_version` and `no_new_privileges`
- Add `json` tag for `additional_gids` in `User` struct
- Add `json` tags for `typ` in `Rlimit`, `Mount`, `LinuxNamespace`
- Add `json` tags for path and ID mapping fields in `Linux`
- Add `json` tags for `file_mode`, `container_id`, `host_id`
2025-09-10 11:54:38 +03:00
Mahmoud-Emad
7635732952 feat: integrate crun module for container config
- Replace manual OCI config generation
- Store `crun.CrunConfig` in `Container` struct
- Expose `crun` config management methods
- Use `crun` module in container factory
- Add `crun_configs` map to factory
`
2025-09-10 11:43:31 +03:00
ITX Oliver Lienhard
6c9f4b54e0 Trigger security scan 2025-09-09 05:33:19 +02:00
ITX Oliver Lienhard
8b218cce03 Add Github Actions Security workflow 2025-09-09 05:33:18 +02:00
ae2c856e7c Merge branch 'development' of github.com:freeflowuniverse/herolib into development
* 'development' of github.com:freeflowuniverse/herolib:
  ...
  add example heromodels call
  add example and heromodels openrpc server
  remove server from gitignore
  clean up and fix openrpc server implementation
  Test the workflow
  feat: Add basic `heropods` container example
  refactor: enhance container lifecycle and Crun executor
  refactor: streamline container setup and dependencies
  refactor: externalize container and image base directories
  feat: Add ExecutorCrun and enable container node creation
  refactor: Migrate container management to heropods module
  refactor: simplify console management and apply fixes
  ...
  ...
  ...
  ...
  ...
  ...
2025-09-09 06:30:52 +04:00
74a23105da ... 2025-09-09 06:30:45 +04:00
50bad9bb7a Merge branch 'development' of https://github.com/freeflowuniverse/herolib into development 2025-09-08 22:00:01 +04:00
6cf8cf5657 ... 2025-09-08 21:59:59 +04:00
Timur Gordon
cd0cec3619 add example heromodels call 2025-09-08 19:50:17 +02:00
Timur Gordon
a20a69f7d8 add example and heromodels openrpc server 2025-09-08 19:48:15 +02:00
Timur Gordon
e856d30874 merge and fix encoding 2025-09-08 19:43:48 +02:00
Timur Gordon
cefbcb6caa remove server from gitignore 2025-09-08 19:37:12 +02:00
Timur Gordon
263febb080 clean up and fix openrpc server implementation 2025-09-08 19:36:53 +02:00
Mahmoud-Emad
9cc411eb4a Test the workflow 2025-09-08 17:30:54 +03:00
Mahmoud-Emad
41c8f7cf6d feat: Add basic heropods container example
- Initialize `heropods` factory using Podman
- Create, start, and stop a custom `alpine` container
- Execute a command within the container
- Add debug log for container command execution
2025-09-08 14:29:26 +03:00
Mahmoud-Emad
196bcebb27 refactor: enhance container lifecycle and Crun executor
- Refactor container definition and creation flow
- Implement idempotent behavior for `container.start()`
- Add comprehensive `ExecutorCrun` support to all Node methods
- Standardize OCI image pulling and rootfs export via Podman
- Update default OCI config for persistent containers and no terminal
2025-09-08 13:54:40 +03:00
Mahmoud-Emad
ef211882af refactor: streamline container setup and dependencies
- Remove `xz-utils` from initial package install
- Remove password/secret check in `obj_init`
- Add on-demand `crun` installation during container create
- Import `herorunner_installer` for `crun` setup
2025-09-07 19:01:08 +03:00
Mahmoud-Emad
7001e8a2a6 refactor: externalize container and image base directories
- Add `base_dir` field to `ContainerFactory`
- Initialize `base_dir` from `CONTAINERS_DIR` env or user home
- Replace hardcoded `/containers` paths with `base_dir` variable
- Update image `created_at` retrieval to use `os.stat`
2025-09-07 16:42:34 +03:00
Mahmoud-Emad
16c01b2e0f feat: Add ExecutorCrun and enable container node creation
- Add ExecutorCrun to Executor type union
- Expose ExecutorCrun.init() as public
- Implement Container.node() to build builder.Node
- Initialize ExecutorCrun and assign to new node
- Set default node properties (platform, cputype)
2025-09-07 16:05:24 +03:00
Mahmoud-Emad
a74129ff90 refactor: Migrate container management to heropods module
- Remove `herorun` module and related scripts
- Introduce `heropods` module for container management
- Enhance `tmux` module with pane clearing and creation
- Update `Container` methods to use `osal.Command` result
- Improve `ContainerFactory` for image & container handling
2025-09-07 15:56:59 +03:00
Mahmoud-Emad
9123c2bcb8 refactor: simplify console management and apply fixes
- Replace ConsoleFactory with global state and functions
- Fix container state check to use `result.output`
- Reformat `osal.exec` calls and map literals
- Streamline environment variable parsing
- Remove redundant blank lines and trailing characters
2025-09-07 14:52:17 +03:00
145c6d8714 ... 2025-09-07 15:27:41 +04:00
cb125e8114 ...
Co-authored-by: Omdanii <mahmmoud.hassanein@gmail.com>
2025-09-07 15:15:41 +04:00
53552b03c2 ... 2025-09-07 14:47:58 +04:00
12316e57bb ... 2025-09-07 14:26:42 +04:00
984013f774 ... 2025-09-07 13:32:33 +04:00
ff0d04f3b6 Merge branch 'development' of https://github.com/freeflowuniverse/herolib into development
# Conflicts:
#	herolib.code-workspace
2025-09-07 13:30:34 +04:00
1abeb6f982 ... 2025-09-07 13:29:23 +04:00
5eb74431c1 Merge branch 'development' of github.com:freeflowuniverse/herolib into development 2025-09-07 13:28:04 +04:00
c9124654f1 ... 2025-09-07 13:28:01 +04:00
35fe19f27a ... 2025-09-07 13:24:43 +04:00
2e57704884 ... 2025-09-07 13:19:43 +04:00
b1bc3e1dc4 ... 2025-09-07 13:14:50 +04:00
36b4d04288 ... 2025-09-07 12:57:32 +04:00
7f52368a2d ... 2025-09-07 11:43:22 +04:00
66dbcae195 ... 2025-09-07 06:40:45 +00:00
a247ad2065 ... 2025-09-07 10:17:16 +04:00
139f46b6c3 bump version to 1.0.33 2025-09-07 08:00:13 +04:00
9f424d9d33 ... 2025-09-07 07:59:58 +04:00
154a5139d9 bump version to 1.0.32 2025-09-07 07:50:13 +04:00
eb81e69bf4 ... 2025-09-07 07:49:47 +04:00
4b41bdc588 ... 2025-09-07 07:40:50 +04:00
9eb89e0411 bump version to 1.0.31 2025-09-07 07:40:09 +04:00
5fcdadcabd bump version to 1.0.30 2025-09-07 07:30:48 +04:00
d542d080fa ... 2025-09-07 07:30:09 +04:00
f6557335ee ... 2025-09-07 07:23:43 +04:00
bbac841427 ... 2025-09-07 07:21:40 +04:00
746d9d16c7 Merge branch 'development' into development_herorun
* development:
  ...
  bump version to 1.0.30
2025-09-07 07:02:09 +04:00
075b6bd124 ... 2025-09-05 14:13:39 +04:00
9174e60d78 Merge branch 'development' of github.com:freeflowuniverse/herolib into development 2025-09-05 14:07:20 +04:00
85b17eeb05 bump version to 1.0.30 2025-09-05 14:07:16 +04:00
Mahmoud-Emad
8d03eb822d feat: add HeroRun remote container management library
- Introduce Executor for remote container orchestration
- Add Container lifecycle management with tmux
- Support Alpine and Alpine Python base images
- Auto-install core dependencies on remote node
- Include full usage examples and updated README
2025-09-03 18:32:47 +03:00
Mahmoud-Emad
0ee57a8075 test: update logger instantiation in test 2025-09-03 11:44:34 +03:00
Mahmoud-Emad
dd400ba6fa style: improve code formatting; refactor module imports
- Apply consistent alignment for struct fields and parameters
- Standardize string literal delimiters to single quotes
- Refactor module import strategy in `models` package
- Enhance asset formatting for precise decimal display
- Remove unused imports and redundant `+}` syntax artifacts
2025-09-03 11:36:02 +03:00
Mahmoud-Emad
4a82bde192 refactor: migrate to redisclient and update V-lang syntax
- Refactor Redis client usage to `herolib.core.redisclient`
- Improve Redis connection error handling and logging
- Update V-lang syntax: string interpolation, `spawn`, key generation
- Expose `herocluster` types and methods as public
- Add `redisclient` usage example in `escalayer` module
2025-09-03 11:22:18 +03:00
Mahmoud-Emad
08bcd3bc56 fix: Fix SSH result for exit code 1 and refactor ping
- Alias `herolib.core` import to `herolib_core`
- Use `herolib_core.platform()` for clarity
- Store `res.output` in `res_output` variable
- Return `res_output` consistently
- Change `SSHResult.tcpport` to `SSHResult.ssh`
2025-09-03 10:41:07 +03:00
Mahmoud-Emad
49bf9dbf80 test: Update ping test assertions
- Use boolean `true` for successful ping
- Use boolean `false` for ping timeout
- Use boolean `false` for unknown host
2025-09-03 10:24:19 +03:00
Omdanii
2b39801164 Merge pull request #142 from freeflowuniverse/development_decartive
test: update ping call parameters in tests
2025-09-03 10:19:18 +03:00
Mahmoud-Emad
5bfaec3cb3 test: update ping call parameters in tests
- Rename `timeout` to `nr_ok` in `addr.ping` calls
- Rename `count` to `retry` in `ping` function calls
- Replace `timeout` with `nr_ok` in `ping` function calls
2025-09-03 10:15:23 +03:00
Omdanii
99427fcbef Merge pull request #141 from freeflowuniverse/development_decartive
Tmux decorative version
2025-09-02 19:34:30 +03:00
Mahmoud-Emad
1bd91cd51a refactor: clean up imports and enhance error handling
- Remove multiple unused imports
- Change `is_running` to return `!bool`
- Update `is_running` calls to handle result type
2025-09-02 19:27:18 +03:00
Mahmoud-Emad
03935c3637 Merge branch 'development' into development_decartive 2025-09-02 19:10:58 +03:00
Mahmoud-Emad
b84e9a046c feat: add declarative tmux pane command management
- Implement Redis-backed command state tracking
- Use MD5 hashing to detect command changes in panes
- Kill and restart pane commands only when necessary
- Ensure bash is the parent process in each pane
- Add pane reset and emptiness checks before command execution
2025-09-02 19:10:34 +03:00
Mahmoud-Emad
b3fe4dd2cd feat: add multi-line command support for tmux panes
- Refactor `send_command` to handle multi-line input
- Implement `send_multiline_command` to execute temp scripts
- Create temporary bash scripts for multi-line commands
- Add documentation and examples for multi-line commands
2025-09-02 16:02:46 +03:00
Mahmoud-Emad
49f15d46bb fix: improve stdin compatibility with tmux pipe-pane
- Replace `io.new_buffered_reader` with raw `os.fd_read`
- Implement manual line buffering for stdin input
- Process any remaining partial line after input stream ends
- Address `tmux pipe-pane` data handling differences
2025-09-02 15:07:14 +03:00
Mahmoud-Emad
cf8e69041d feat: improve tmux_logger with flexible argument parsing
- Add structured argument parsing to `tmux_logger` utility
- Introduce `--no-log` and `--logreset` command-line options
- Enable dynamic log path resolution and pane-specific directories
- Simplify tmux pane logging integration, remove buffer script
- Standardize log category output padding in `categorize_output`
2025-09-02 13:47:35 +03:00
Timur Gordon
89ef8442a3 Merge branch 'development' of github.com:freeflowuniverse/herolib into development 2025-09-02 10:15:03 +02:00
Timur Gordon
9bbe8abd6b rpc fixes 2025-09-02 10:13:55 +02:00
de763f14f6 ... 2025-09-02 09:36:21 +02:00
d5f06ef971 ... 2025-09-02 09:24:49 +02:00
357a9e58ba ... 2025-09-02 09:22:25 +02:00
635950f33a ... 2025-09-02 09:21:26 +02:00
ad71b6943e ... 2025-09-02 09:18:36 +02:00
9beb763c93 Merge branch 'development_decartive' into development
* development_decartive:
  ...
  ...
  ...
  ...
  ...
  ...
  feat: add real-time logging for tmux panes
  ...
  refactor: Migrate from `vweb` to `veb` web framework
  feat: Add robust cross-platform port availability check
  Update the exe path
  chore: remove deprecated tmux example scripts and testing docs
  feat: Implement comprehensive process cleanup for tmux
  feat: implement dynamic pane resizing
  ...
  ...
  feat: Add declarative tmux module functions
2025-09-02 09:10:20 +02:00
40455a8c2e ... 2025-09-02 09:09:21 +02:00
418a38527a ... 2025-09-02 08:52:51 +02:00
3af0aef6c1 ... 2025-09-02 08:44:44 +02:00
c9dc8fb44b Merge branch 'development_decartive' of github.com:freeflowuniverse/herolib into development_decartive 2025-09-02 07:49:16 +02:00
18f4471d3f ... 2025-09-02 07:49:10 +02:00
b0f82ac834 ... 2025-09-02 07:28:13 +02:00
ff1b343a95 ... 2025-09-02 06:54:04 +02:00
ITX Oliver Lienhard
5255006b92 Trigger security scan 2025-09-02 01:58:41 +02:00
ITX Oliver Lienhard
38dd076cb9 Add Github Actions Security workflow 2025-09-02 01:58:39 +02:00
Mahmoud-Emad
52a1d2f80d feat: add real-time logging for tmux panes
- Introduce `tmux_logger` app for categorized output
- Implement pane logging via `tmux pipe-pane`
- Add `log`, `logpath`, `logreset` options to panes
- Update `Pane` struct with logging state and cleanup
- Refactor `logger.new` to use `LoggerFactoryArgs`
2025-09-01 19:48:15 +03:00
6fbca85d0c Merge branch 'development_decartive' of github.com:freeflowuniverse/herolib into development_decartive 2025-09-01 16:15:27 +02:00
8ee02d175e ... 2025-09-01 16:15:25 +02:00
Mahmoud-Emad
4746337b24 Merge branch 'development' into development_decartive 2025-09-01 13:11:03 +03:00
Mahmoud-Emad
46a3bcb840 refactor: Migrate from vweb to veb web framework
- Update all references from `vweb` to `veb`
- Add `veb.StaticHandler` to `Playground` struct
- Ensure error propagation for static file serving calls
- Apply consistent indentation across various module definitions
- Adjust documentation and comments for `veb` framework
2025-09-01 13:00:17 +03:00
Mahmoud-Emad
dde5f2f7e6 feat: Add robust cross-platform port availability check
- Introduce `port_check_available` function
- Use platform-specific tools (`lsof`, `ss`, `netstat`)
- Fallback to socket binding for port checks
- Integrate port check before running `ttyd`
- Simplify `tmux kill-session` error handling
2025-09-01 12:51:13 +03:00
Mahmoud-Emad
c7724f0779 Update the exe path 2025-09-01 12:05:21 +03:00
c702354260 Merge branch 'development' into development_decartive
* development:
  fix heromodels
2025-09-01 07:49:21 +02:00
Mahmoud-Emad
4afedc6541 chore: remove deprecated tmux example scripts and testing docs
- Delete `TESTING.md`
- Remove `tmux_cleanup.heroscript`
- Remove `tmux_setup.heroscript`
- Update `cleanup_test.heroscript` to delete session
2025-08-31 19:54:16 +03:00
Mahmoud-Emad
97760cfe87 feat: Implement comprehensive process cleanup for tmux
- Add `Pane.kill_processes` for main and child processes
- Include fallback process group cleanup for panes
- Implement window-level process cleanup
- Integrate session-level process cleanup
- Add tmux process cleanup test scripts
2025-08-31 19:26:45 +03:00
Mahmoud-Emad
b957394d2a Merge branch 'development_decartive' of https://github.com/freeflowuniverse/herolib into development_decartive 2025-08-31 17:56:14 +03:00
Mahmoud-Emad
7d28129f06 feat: implement dynamic pane resizing
- Add `resize_panes_equal()` to `Window`.
- Dynamically apply `tmux` layouts based on pane count.
- Implement `get_width()` and `get_height()` for `Pane`.
- Update test to create 4 panes and use equal resizing.
2025-08-31 17:56:03 +03:00
Timur Gordon
ab80ba8628 fix heromodels 2025-08-31 15:12:14 +02:00
cb43ec7f1a ... 2025-08-31 13:46:27 +02:00
9657e9aa97 Merge branch 'development' into development_decartive
* development: (53 commits)
  ...
  feat: Implement theming and modal UI improvements
  ...
  ...
  ...
  ...
  ...
  ...
  zinit client fixes
  git herocmd improvements
  ...
  ...
  ...
  ...
  ...
  ...
  ...
  ...
  ...
  ...
  ...
2025-08-31 13:22:58 +02:00
a25a12d4c9 ... 2025-08-31 13:22:52 +02:00
738bb16084 Merge branch 'development' of github.com:freeflowuniverse/herolib into development 2025-08-31 13:11:45 +02:00
f9717f8f5d ... 2025-08-31 13:11:43 +02:00
Mahmoud-Emad
4b0b5a26f8 feat: Add declarative tmux module functions
- Implement `tmux.session_ensure` for idempotent create
- Implement `tmux.window_ensure` with 1 to 16 pane layouts
- Implement `tmux.pane_ensure` to configure individual panes
- Add new declarative tmux example scripts
- Update docs for imperative and declarative paradigms
2025-08-31 11:59:23 +03:00
Mahmoud-Emad
0e8fdb0149 feat: Implement theming and modal UI improvements
- Introduce CSS custom properties for theming
- Add light theme support via `prefers-color-scheme`
- Enhance modal overlay, centering, and styling
- Improve modal responsiveness across breakpoints
- Remove prompt template and output copy buttons
2025-08-31 10:55:43 +03:00
2c7eaa4f5d ... 2025-08-30 12:37:18 +02:00
58aee3916c ... 2025-08-30 11:31:49 +02:00
79d2bb49f9 ... 2025-08-30 11:26:36 +02:00
6daffaeb94 ... 2025-08-29 12:51:19 +02:00
6edbfef12a ... 2025-08-29 10:44:46 +02:00
b7b89eece7 Merge branch 'development' of github.com:freeflowuniverse/herolib into development 2025-08-29 10:35:29 +02:00
90a3ce1181 ... 2025-08-29 10:35:27 +02:00
Timur Gordon
c813546085 Merge branch 'development' of github.com:freeflowuniverse/herolib into development 2025-08-29 10:18:25 +02:00
Timur Gordon
b0b1fbf2c2 zinit client fixes 2025-08-29 10:17:51 +02:00
Timur Gordon
3d86ec7cf5 git herocmd improvements 2025-08-29 10:17:34 +02:00
ce6cf3aa9c ... 2025-08-29 09:48:44 +02:00
03bb86bd72 ... 2025-08-29 09:48:13 +02:00
b146261432 ... 2025-08-29 09:47:54 +02:00
b29468c0c2 ... 2025-08-29 06:31:29 +02:00
8d1656c679 ... 2025-08-29 06:27:37 +02:00
0f6d6f731a ... 2025-08-29 06:13:50 +02:00
0f2d9f0aba ... 2025-08-28 21:28:03 +02:00
0221c0a28c ... 2025-08-28 21:21:57 +02:00
03961b291b ... 2025-08-28 20:42:59 +02:00
e89bd8ce24 ... 2025-08-28 19:22:14 +02:00
66d2ef2d97 ... 2025-08-28 19:18:56 +02:00
0a02ea353a ... 2025-08-28 18:46:24 +02:00
03c296ec2f ... 2025-08-28 18:39:18 +02:00
a96bebfd65 ... 2025-08-28 18:37:50 +02:00
fac9276479 ... 2025-08-28 18:27:32 +02:00
8440b18e2f ... 2025-08-28 17:37:57 +02:00
e340ad01ea ... 2025-08-28 17:19:32 +02:00
ae1f9d4477 .. 2025-08-28 16:12:34 +02:00
7b8ca007b7 ... 2025-08-28 16:10:59 +02:00
fb87adf87d ... 2025-08-28 16:02:28 +02:00
d52aa5dbd4 .l. 2025-08-28 14:40:09 +02:00
0bf586f748 Merge branch 'development_decartive' into development_builders
* development_decartive:
  refactor: use osal.processinfo_get for process stats
  feat: add declarative tmux and ttyd management

# Conflicts:
#	lib/osal/tmux/readme.md
2025-08-28 14:26:30 +02:00
a4472f095e Merge branch 'development' into development_builders
* development:
  minor example fixes
  feat: add comprehensive SSH agent management command
  refactor: Harden and improve SSH agent module
  ...
  feat: add editable ttyd dashboard mode
  feat: add CLI for dashboard management and 4-pane layout
  fix: Fix build
  ...
  refactor: update SSH agent examples and module structure
  feat: add tmux dashboard with ttyd integration
  refactor: Remove is_tmux_server_not_running_error function
  wip: pushing the code to sync in other branch
  refactor: Improve tmux API consistency and formatting

# Conflicts:
#	lib/osal/core/net.v
#	lib/virt/podman/factory.v
2025-08-28 14:26:06 +02:00
f5ca193fb4 ... 2025-08-28 14:25:07 +02:00
3f9844fd93 ... 2025-08-28 14:03:29 +02:00
76efe0438a ... 2025-08-28 13:29:17 +02:00
12c197207c ... 2025-08-28 13:28:05 +02:00
60fd795b1f ... 2025-08-28 12:02:48 +02:00
Mahmoud-Emad
ccfe02b1ee refactor: use osal.processinfo_get for process stats
- Replace `ps` command parsing with `osal.processinfo_get`
- Remove custom system memory detection and caching
- Update ProcessStats to use `osal` process info fields
- Ignore expected errors when stopping ttyd
- Add logging for ttyd stop operations
2025-08-28 12:55:12 +03:00
Mahmoud-Emad
b6324849a4 feat: add declarative tmux and ttyd management
- Implement `tmux.pane_split` action
- Add declarative `tmux.session_ttyd` and `tmux.window_ttyd`
- Include `tmux.session_ttyd_stop`, `window_ttyd_stop`, `ttyd_stop_all`
- Update tmux documentation and add usage examples
- Improve robustness of tmux session and window scanning
2025-08-28 12:45:46 +03:00
c10a7f2e7b ... 2025-08-28 09:17:10 +02:00
049f2316bd ... 2025-08-28 07:28:43 +02:00
4af635c4d1 Merge branch 'development_builders' of github.com:freeflowuniverse/herolib into development_builders 2025-08-28 05:39:53 +02:00
d1ec4ff568 lima installer 2025-08-28 05:39:51 +02:00
Mahmoud-Emad
13223dc03d chore: remove buildah example and run scripts
- Remove `buildah_example` script
- Remove `buildah_run_clean` script
- Remove `buildah_run_mdbook` script
- Remove `buildah_run` script
2025-08-27 13:11:57 +03:00
Mahmoud-Emad
9d79b6f2e2 feat: introduce consolidated Podman module with dual APIs
- Restructure Podman module into sub-files
- Introduce Simple API for quick Podman operations
- Add Podman machine management (init, start, list)
- Enhance Buildah integration with structured errors
- Define specific error types for Podman operations
- Update documentation and add comprehensive demo script
2025-08-27 13:10:53 +03:00
db9d2b5a0a ... 2025-08-27 10:20:52 +02:00
791988c420 ... 2025-08-27 09:57:06 +02:00
Timur Gordon
566d871399 minor example fixes 2025-08-27 09:41:33 +02:00
cbc6a9df2d .. 2025-08-27 09:36:11 +02:00
cace08d36c ... 2025-08-27 09:23:54 +02:00
a1fcdc1005 ... 2025-08-27 07:23:44 +02:00
c4d4dd5560 ... 2025-08-27 07:12:35 +02:00
Mahmoud-Emad
1228441fd6 feat: Add Buildah builder API and refactor module
- Introduce `Builder` struct for image creation
- Implement `PodmanFactory` methods for builder lifecycle
- Rename `herocontainers` module to `podman`
- Update `PodmanFactory.new` with platform checks
- Revise documentation for `podman` and Buildah usage
2025-08-26 20:28:38 +03:00
Mahmoud-Emad
ae5ab3133f Merge branch 'development_builders' of https://github.com/freeflowuniverse/herolib into development_builders 2025-08-26 14:24:34 +03:00
Mahmoud-Emad
b4c0d33b81 refactor: Update Podman install and uninstall methods
- Use native package managers for Linux and macOS
- Remove direct download and package file handling
- Add process termination during uninstallation
- Simplify temporary file cleanup in destroy
- Add checks for installed status in destroy
2025-08-26 14:24:18 +03:00
24ec468d37 ... 2025-08-26 11:36:53 +02:00
Omdanii
582184f51e Merge pull request #135 from freeflowuniverse/development_sshagent
Improve SSH agent module
2025-08-26 10:40:10 +03:00
f30d1fd503 ... 2025-08-26 04:53:39 +02:00
Mahmoud-Emad
e341f83f0f feat: add comprehensive SSH agent management command
- Introduce `hero sshagent` for full SSH agent management
- Implement `profile`, `push`, `auth`, `status` subcommands
- Enable smart key loading and shell profile integration
- Support remote key deployment and authorization verification
- Use `~/.ssh/hero-agent.sock` and ensure secure permissions
2025-08-25 17:22:13 +03:00
Mahmoud-Emad
ab6808c5f9 Merge branch 'development' into development_sshagent 2025-08-25 16:38:46 +03:00
Omdanii
289bfb3a98 Merge pull request #117 from freeflowuniverse/development_tmux
Improve tmux API consistency and formatting
2025-08-25 16:36:25 +03:00
Mahmoud-Emad
32e7a6df4f refactor: Harden and improve SSH agent module
- Add extensive security validations for SSH agent
- Implement robust `ssh-agent` auto-start script
- Enhance `sshagent` operations with improved error handling
- Revamp `sshagent` test suite for comprehensive coverage
- Update `sshagent` README with detailed documentation
2025-08-25 16:32:20 +03:00
50545ef5c1 ... 2025-08-25 12:53:25 +02:00
621faa73a5 Merge branch 'development_tmux' of github.com:freeflowuniverse/herolib into development_tmux 2025-08-25 12:04:43 +02:00
ffa5447e6f ... 2025-08-25 12:04:40 +02:00
Mahmoud-Emad
a62147d7cc feat: add editable ttyd dashboard mode
- Implement `-editable` CLI argument
- Configure ttyd for read/write access
- Introduce `TtydArgs` struct for ttyd parameters
- Update help message with ttyd modes
- Streamline Hero Web startup command
2025-08-25 11:52:13 +03:00
Mahmoud-Emad
dcb9714599 feat: add CLI for dashboard management and 4-pane layout
- Implement CLI for start, stop, status, restart
- Refactor dashboard setup into `start_dashboard` function
- Add `stop_dashboard` and `show_status` functions
- Expand tmux dashboard layout to 4 panes (2x2 grid)
- Integrate "Hero Web" service into dashboard panes
2025-08-25 10:16:10 +03:00
a99af1dfdd Merge branch 'development' into development_builders
* development:
  ...
  ...
  feat: add persistent AI chat interface
  feat: implement workspace search and improve UI
  feat: add ignore filtering to directory listing
  feat: add workspace management and file preview
  feat: Add workspace selection synchronization
  feat: Add directory listing functionality
  feat: redesign UI for improved file explorer and workspaces
  docs: add HeroLib Web UI documentation
  feat: improve Heroprompt UI and refactor modules
  feat: add modular web UI features
  bump version to 1.0.29
2025-08-25 09:07:47 +02:00
bf999d8fcb ... 2025-08-25 09:07:00 +02:00
Mahmoud-Emad
750e34cbe4 fix: Fix build 2025-08-25 09:43:37 +03:00
Mahmoud-Emad
25f4e4f03e Merge branch 'development' into development_tmux 2025-08-25 09:40:18 +03:00
Omdanii
0bc6150986 Merge pull request #118 from freeflowuniverse/development_heroprompt
Development heroprompt
2025-08-25 09:39:47 +03:00
4c1ed80b85 ... 2025-08-25 07:16:16 +02:00
85eaee4c0a ... 2025-08-25 07:14:11 +02:00
161f6786bd Merge branch 'development' into development_tmux
* development:
  ...

# Conflicts:
#	lib/osal/sshagent/agent.v
#	lib/osal/sshagent/play.v
2025-08-25 07:00:06 +02:00
692838566a Merge branch 'development' into development_heroprompt
* development:
  ...
2025-08-25 06:59:37 +02:00
856a5add22 ... 2025-08-25 06:59:30 +02:00
5f75c542df ... 2025-08-25 06:34:39 +02:00
43e7c087db Merge branch 'development' into development_tmux
* development:
  ...
  ...
  ...
  ...

# Conflicts:
#	examples/osal/sshagent.vsh
#	examples/osal/sshagent/sshagent_example.v
#	examples/osal/tmux.vsh
#	lib/osal/sshagent/agent.v
#	lib/osal/sshagent/builder_integration.v
#	lib/osal/tmux/tmux_pane.v
#	lib/osal/tmux/tmux_scan.v
#	lib/osal/tmux/tmux_session.v
#	lib/osal/tmux/tmux_window.v
2025-08-25 06:34:03 +02:00
e0a81f9525 Merge branch 'development' into development_heroprompt
* development:
  ...
  ...

# Conflicts:
#	lib/threefold/grid4/datamodel/model_node.v
2025-08-25 06:33:07 +02:00
80741a3500 ... 2025-08-25 06:31:32 +02:00
c6d703b860 ... 2025-08-25 06:29:42 +02:00
836c87fbec ... 2025-08-25 06:28:42 +02:00
5f683ec4a8 ... 2025-08-25 06:09:51 +02:00
77d9b5c869 Merge branch 'development' into development_heroprompt
* development:
  ...
  ...
  ...
  ...
  ...
  ...
  ...
  ...
  ...
  ...
  ...
  ...
  ...
  ...
  ...
  ...
  ...

# Conflicts:
#	lib/threefold/grid4/datamodel/model_slice_compute.v
#	lib/threefold/grid4/datamodel/model_slice_storage.v
2025-08-25 06:01:35 +02:00
607b2b0881 ... 2025-08-25 05:58:44 +02:00
01163ef534 ... 2025-08-25 05:44:45 +02:00
Mahmoud-Emad
a37dbd2438 refactor: update SSH agent examples and module structure
- Refactor `gittools` to remove `sshagent` import
- Update `sshagent.loaded()` to use `ssh-add -l` command
- Relocate and expose `remote_copy` and `remote_auth` functions
- Improve SSH agent examples and remove Linux tests
- Optimize `sshagent` module and `play` function imports
2025-08-24 23:54:57 +03:00
Mahmoud-Emad
9945cfb52c Merge branch 'development' into development_tmux 2025-08-24 23:15:34 +03:00
Mahmoud-Emad
25327053b9 feat: add tmux dashboard with ttyd integration
- Create script for 3-pane tmux dashboard
- Run Python HTTP server, counter, and htop in panes
- Add `run_ttyd` function to `Session` struct
- Add `run_ttyd` function to `Window` struct
- Expose tmux session and window via ttyd
2025-08-24 23:12:32 +03:00
Mahmoud-Emad
426a53a50d refactor: Remove is_tmux_server_not_running_error function 2025-08-24 18:10:30 +03:00
Mahmoud-Emad
b26893bf45 wip: pushing the code to sync in other branch 2025-08-24 17:58:09 +03:00
4e20df3eb8 ... 2025-08-24 16:42:07 +02:00
a2a9b07238 ... 2025-08-24 16:40:07 +02:00
8532373e7e ... 2025-08-24 16:19:41 +02:00
c7b2ea9e2a ... 2025-08-24 16:00:13 +02:00
698724f810 ... 2025-08-24 15:43:07 +02:00
4f54551f14 ... 2025-08-24 15:42:01 +02:00
Mahmoud-Emad
117c9ac67c refactor: Improve tmux API consistency and formatting
- Refactor `logs_get_new` to use `LogsGetArgs` struct
- Return window as reference from `window_new`
- Standardize indentation and spacing
- Remove excessive blank lines
- Comment out initial example usage
2025-08-24 16:31:04 +03:00
e47d311c99 ... 2025-08-24 15:28:57 +02:00
6de2153f11 ... 2025-08-24 15:24:52 +02:00
Mahmoud-Emad
0e7344ae4a feat: add persistent AI chat interface
- Implement persistent AI chat with conversation history.
- Add chat sidebar for conversation management (create, load, delete).
- Enhance message display with markdown, copy, regenerate actions.
- Integrate interactive chat input (auto-resize, char count, typing indicator).
- Apply comprehensive responsive and accessibility styles to chat UI.
2025-08-24 16:13:25 +03:00
810cbda176 ... 2025-08-24 15:10:03 +02:00
d07aec8434 ... 2025-08-24 15:02:22 +02:00
4ab65ac61b ... 2025-08-24 14:56:20 +02:00
1dd8c29735 ... 2025-08-24 14:47:48 +02:00
e7a36f47e8 ... 2025-08-24 14:41:12 +02:00
Mahmoud-Emad
7fe03b5a5d feat: implement workspace search and improve UI
- Add workspace search API endpoint
- Integrate workspace search into frontend UI
- Implement synchronized scrolling for code previews
- Standardize API error/success JSON responses
- Improve file tree loading animations & interaction
2025-08-24 15:14:25 +03:00
9f39481cb4 ... 2025-08-24 14:02:41 +02:00
2253ef71e6 ... 2025-08-24 13:56:54 +02:00
Mahmoud-Emad
cd512813e3 feat: add ignore filtering to directory listing
- Add `list_directory_filtered` function with ignore logic
- Update `default_gitignore` with common VCS and build patterns
- Integrate ignore filtering into `Workspace.list_dir`
- Rename project to HeroPrompt in README
- Update README features and usage descriptions
2025-08-24 13:57:25 +03:00
Mahmoud-Emad
d6ea18e6db feat: add workspace management and file preview
- Add workspace update and delete API endpoints
- Redesign selected files display to use interactive cards
- Implement VS Code-style modal for file content preview
- Enhance file tree with animations and local state
- Update UI styles for explorer, forms, and modals
2025-08-24 13:40:51 +03:00
Mahmoud-Emad
cc93081b15 feat: Add workspace selection synchronization
- Create `codewalker` module with file system utilities
- Refactor `Workspace` file operations to use `codewalker`
- Add `include_tree` flag to `HeropromptChild` struct
- Implement new `/selection` API endpoint for workspace
- Sync frontend selection state to backend via new API
2025-08-24 12:58:09 +03:00
Mahmoud-Emad
6098f166bb feat: Add directory listing functionality
- Add `list_dir` function to `Workspace` struct
- Implement path handling and directory scanning logic
- Refine struct formatting for `Node`, `ComputeSlice`, `StorageSlice`
- Update `StorageSlice.pricing_policy` comment
- Adjust whitespace in CSS styles
2025-08-24 12:00:12 +03:00
Mahmoud-Emad
3050433cfd Merge branch 'development' into development_heroprompt 2025-08-24 11:35:08 +03:00
Mahmoud-Emad
de9e310867 feat: redesign UI for improved file explorer and workspaces
- Refactor file tree logic into `SimpleFileTree` class
- Implement new explorer with collapse, refresh, search, and selection controls
- Redesign selection, prompt, and chat workspaces with new layouts and styles
- Introduce dedicated CSS icon set for various UI elements
- Add prompt generation and clipboard copy functionality for prompt output
2025-08-24 11:34:30 +03:00
9398d653d3 ... 2025-08-23 14:06:15 +02:00
66240aa9f2 ... 2025-08-22 14:33:01 +02:00
Mahmoud-Emad
03de3a6aee docs: add HeroLib Web UI documentation
- Add quick start guide with code example
- List key features of the UI
- Detail built-in tools and their paths
2025-08-21 20:04:25 +03:00
Mahmoud-Emad
cf187d46b3 feat: improve Heroprompt UI and refactor modules
- Refactor all UI rendering logic into a single `ui` module
- Centralize static assets serving to `/static` directory
- Redesign Heroprompt page with Bootstrap 5 components
- Enhance workspace management and file tree interactions
- Add Bootstrap modal support for UI dialogs
2025-08-21 20:01:43 +03:00
Mahmoud-Emad
066f339b78 Merge branch 'development_heroprompt' of https://github.com/freeflowuniverse/herolib into development_heroprompt 2025-08-21 18:28:49 +03:00
Mahmoud-Emad
68dd957421 feat: add modular web UI features
- Enable `web` command to start UI server
- Centralize web server setup and static serving
- Implement modular UI for chat and script editor
- Refactor Heroprompt UI into its own module
- Introduce dynamic theme switching and mobile menu
2025-08-21 18:28:17 +03:00
b168d647da ... 2025-08-21 17:18:41 +02:00
3f46a35f7b ... 2025-08-21 12:45:03 +02:00
e6021c0bde ... 2025-08-21 12:44:42 +02:00
9af7a62381 ... 2025-08-21 12:43:03 +02:00
245d45bb6b ... 2025-08-21 12:37:35 +02:00
238c35d45b ... 2025-08-21 12:36:54 +02:00
df3817120f ... 2025-08-21 12:35:06 +02:00
2a38221d7f bump version to 1.0.29 2025-08-21 12:27:48 +02:00
40b3911781 ... 2025-08-21 12:21:52 +02:00
febe87c55e ... 2025-08-21 12:17:40 +02:00
e8d6193d06 Merge branch 'development' into development_heroprompt
* development:
  ...
2025-08-21 12:16:42 +02:00
1d98724c02 ... 2025-08-21 12:16:32 +02:00
26731c38b5 ... 2025-08-21 12:13:36 +02:00
a484da769c Merge branch 'development_heroprompt' of github.com:freeflowuniverse/herolib into development_heroprompt 2025-08-21 12:11:11 +02:00
cbccce3413 ... 2025-08-21 12:11:09 +02:00
Mahmoud-Emad
27c8c06cdb chore: Comment the web ui package 2025-08-21 13:10:44 +03:00
Mahmoud-Emad
35eee2dcad Merge branch 'development_heroprompt' of https://github.com/freeflowuniverse/herolib into development_heroprompt 2025-08-21 13:07:09 +03:00
cba4a6d7c1 ... 2025-08-21 12:06:21 +02:00
1217d7b10d ... 2025-08-21 12:06:03 +02:00
Mahmoud-Emad
cfd5711c86 chore: comment out web command functionality 2025-08-21 13:06:01 +03:00
9642922445 ... 2025-08-21 12:05:20 +02:00
9b2b7283c0 ... 2025-08-21 12:02:28 +02:00
9658f1af8d ... 2025-08-21 12:01:36 +02:00
13bed3d48a ... 2025-08-21 11:59:06 +02:00
e620dfc6e3 Merge branch 'development' of github.com:freeflowuniverse/herolib into development
* 'development' of github.com:freeflowuniverse/herolib:
  remove const from default field value
2025-08-21 11:38:07 +02:00
1171b7b6d6 Merge branch 'development_heroprompt' of github.com:freeflowuniverse/herolib into development_heroprompt 2025-08-21 11:37:19 +02:00
3029bf661a ... 2025-08-21 11:37:17 +02:00
Timur Gordon
26c945ed08 remove const from default field value 2025-08-21 11:37:11 +02:00
1b90ce41e6 ... 2025-08-21 11:15:08 +02:00
e0a8bc32e7 .. 2025-08-21 11:10:13 +02:00
Mahmoud-Emad
f5d9c6019b Merge branch 'development' into development_heroprompt 2025-08-21 11:06:57 +03:00
Mahmoud-Emad
27f48de1f1 feat: Add directory and file selection
- Add button to select directories
- Implement `addDirToSelection` API call
- Refactor file selection to `addFileToSelection`
- Update file selection button title
- Remove commented preview logic from file links
2025-08-21 10:59:20 +03:00
add4fb5c48 ... 2025-08-21 09:55:30 +02:00
17cdfd8a0d ... 2025-08-21 09:49:25 +02:00
Mahmoud-Emad
854eb9972b feat: integrate Heroprompt UI and backend
- Replace generic UI with dedicated Heroprompt web interface
- Implement new Heroprompt-specific backend APIs
- Develop client-side logic for file browsing and selection
- Enhance workspace configuration and management capabilities
- Remove deprecated generic UI modules and code
2025-08-21 10:49:02 +03:00
c0339a0922 ... 2025-08-21 09:48:50 +02:00
601e5db76a , 2025-08-21 09:45:41 +02:00
b109299210 ... 2025-08-21 09:38:20 +02:00
082dbed910 ... 2025-08-21 09:07:29 +02:00
6e32a01faa ... 2025-08-21 08:38:40 +02:00
d73fe6eb25 ... 2025-08-20 18:57:32 +02:00
4a0fd8edde ... 2025-08-20 18:44:42 +02:00
34202de296 ... 2025-08-20 18:39:52 +02:00
3988548fe9 ... 2025-08-19 05:57:31 +02:00
3bcb6bee80 ... 2025-08-19 05:51:43 +02:00
7e33acb425 ... 2025-08-18 17:17:10 +02:00
75d20fd8e1 ... 2025-08-18 17:16:03 +02:00
Mahmoud-Emad
c38fdd86ac Merge branch 'development' into development_heroprompt 2025-08-18 13:38:13 +03:00
Mahmoud-Emad
9069816db1 feat: implement full heroprompt workspace management
- Add create, save, get, list, and delete for workspaces
- Enable adding and removing files/dirs by path or name
- Integrate codewalker for recursive file discovery
- Make workspaces stateful with created/updated timestamps
- Update example to demonstrate new lifecycle methods
2025-08-18 09:51:16 +03:00
1903ebe045 ... 2025-08-18 07:30:00 +02:00
3dee0d7eef Merge branch 'development_codewalker' of github.com:freeflowuniverse/herolib into development_codewalker 2025-08-18 07:23:29 +02:00
ba85e91c58 .. 2025-08-18 07:23:27 +02:00
Mahmoud-Emad
1ed08b3ca4 fix: add the removed README 2025-08-17 20:19:41 +03:00
Mahmoud-Emad
bcee46fa15 refactor: overhaul codewalker with improved parser and ignore logic
- Implement level-scoped .gitignore/.heroignore matching
- Rewrite directory walker to use new ignore matcher
- Replace filemap parser with robust header-based logic
- Support `FILE`, `FILECHANGE`, and legacy header formats
- Add extensive tests for new parsing and ignore features
2025-08-17 15:23:15 +03:00
f3449d6812 ... 2025-08-17 11:07:26 +02:00
Mahmoud-Emad
3c5e0a053e Merge branch 'development' into development_heroprompt 2025-08-17 11:42:16 +03:00
Mahmoud-Emad
f6c077c6b5 refactor: simplify heroprompt workspace selection model
- Introduce HeropromptChild to unify file and dir items
- Replace nested Dir/File structs with a flat `children` list
- Generate prompt content by traversing the filesystem on-demand
- Add `workspace.add_file` for direct file selection
- Simplify `workspace.add_dir` to only add the directory path
2025-08-17 11:41:29 +03:00
df5d91e7b6 ... 2025-08-17 10:41:09 +02:00
25e01e308c ... 2025-08-17 10:13:45 +02:00
7204aff27e ... 2025-08-17 10:04:58 +02:00
cd91734a84 ... 2025-08-16 19:51:06 +02:00
6306883463 ... 2025-08-16 19:42:08 +02:00
42bfecffb6 ... 2025-08-16 19:37:42 +02:00
f7d5415484 ... 2025-08-16 19:27:31 +02:00
5825640c2c ... 2025-08-16 17:45:04 +02:00
de60c5f78e ... 2025-08-16 11:23:58 +02:00
be19609855 ... 2025-08-16 10:07:35 +02:00
27bc172257 ... 2025-08-16 07:31:32 +02:00
6732928156 ... 2025-08-16 05:21:52 +02:00
3bd1117210 ... 2025-08-16 05:20:51 +02:00
1cd8e8c299 ... 2025-08-16 05:13:18 +02:00
97d506ecbf ... 2025-08-15 17:57:16 +02:00
43ffedfad8 ... 2025-08-15 08:52:46 +02:00
71298a9704 ... 2025-08-15 08:25:00 +02:00
e76f558f97 ... 2025-08-15 07:41:10 +02:00
e030309b7f ... 2025-08-15 07:09:40 +02:00
e77f923cd2 ... 2025-08-15 06:30:12 +02:00
bd86f2c4f7 ... 2025-08-15 06:20:00 +02:00
Mahmoud-Emad
2d00d6cf9f feat: implement workspace file tree listing
- Add `list()` method to generate a full workspace file tree
- Introduce `WorkspaceItem` and `WorkspaceList` structs
- Remove `HeropromptSession` to simplify the public API
- Rename Heroscript action to `heropromptworkspace.configure`
- Enable full heroscript encoding/decoding for workspaces
2025-08-14 15:45:26 +03:00
Mahmoud-Emad
a58d72615d feat: Add recursive directory selection and enhance prompt builder
- Add `select_all` option to recursively add directory contents
- Implement `select_all_files_and_dirs` for file traversal
- Rework prompt building with file tree and content formatters
- Improve `get_file_extension` to handle dotfiles and special files
- Update prompt template to use new structured data model
2025-08-14 10:56:05 +03:00
Mahmoud-Emad
14771ed944 feat: add heroprompt module for prompt generation
- Introduce sessions and workspaces for managing context
- Allow adding directories and selecting files
- Generate structured prompts with file maps and content
- Add example script and a prompt template
- Define core data models like `HeropromptWorkspace`
2025-08-13 20:13:01 +03:00
Mahmoud-Emad
a6d4a23172 feat: add Heroprompt workspace management UI
- Add HTML, CSS, and JS for the Heroprompt feature
- Implement a three-panel UI for workspaces and files
- Add logic for creating/deleting workspaces in localStorage
- Enable adding directories and selecting files for
2025-08-13 15:37:36 +03:00
Mahmoud-Emad
5c77c6bd8d fix: Rename reporomt to heroprompt 2025-08-13 14:17:29 +03:00
b0ff9e3fbf ... 2025-08-13 13:12:55 +02:00
Mahmoud-Emad
3f82240564 feat: add web command to run Hero UI
- Add `web` command to start the Hero UI server
- Introduce `--host`, `--port`, and `--open` flags
- Implement cross-platform browser opening
- Update UI factory arguments for server configuration
2025-08-13 14:08:00 +03:00
06a89aead9 Merge branch 'development' of github.com:freeflowuniverse/herolib into development
# Conflicts:
#	lib/develop/gittools/gittools_do.v
2025-08-13 12:10:21 +02:00
23a723e17f ... 2025-08-13 12:09:14 +02:00
1501a09e62 ... 2025-08-13 12:09:11 +02:00
Omdanii
1f9b8c1e76 Merge pull request #112 from freeflowuniverse/development_fix_git_clone
Prevent double clone for clone command with URL
2025-08-13 13:08:31 +03:00
Mahmoud-Emad
f7ed2ea31e fix: prevent double clone for clone command with URL
- Differentiate logic when a URL is used for the clone command.
- Parse URL to get identifiers without cloning the repository.
- This avoids an implicit clone before the explicit one.
- Retain original `get_repo` behavior for other commands.
2025-08-13 13:07:30 +03:00
15aeb136b2 ... 2025-08-13 10:12:57 +02:00
50f33e9303 ... 2025-08-13 10:03:33 +02:00
f026565f77 ... 2025-08-13 10:01:09 +02:00
0845feffac ... 2025-08-13 09:48:56 +02:00
55f0621983 ... 2025-08-13 09:35:58 +02:00
75363d7aeb ... 2025-08-13 08:55:38 +02:00
1f9bc11a2e ... 2025-08-13 08:49:44 +02:00
aab018925d ... 2025-08-13 07:23:14 +02:00
5fa361256a ... 2025-08-13 07:18:02 +02:00
42fe7b0a0d Merge branch 'development_fix_docusaurus' of github.com:freeflowuniverse/herolib into development_fix_docusaurus
* 'development_fix_docusaurus' of github.com:freeflowuniverse/herolib:
  refactor: Improve docusaurus import and site handling
2025-08-13 05:59:46 +02:00
011e5b039e ... 2025-08-13 05:59:40 +02:00
Mahmoud-Emad
e9bcf6ef69 refactor: Improve docusaurus import and site handling
- Simplify command logic to use a single defined site
- Enhance git import to resolve paths relative to project root
- Add `docusaurus.export` action to trigger `build_publish`
- Change asset import destination from `docs` to `static`
- Add `dsite_get_only` helper for simplified site access
2025-08-13 04:19:32 +03:00
f885563982 Co-authored-by: Omdanii <mahmmoud.hassanein@gmail.com> 2025-08-12 16:01:27 +02:00
ffff44f347 .. 2025-08-12 15:52:13 +02:00
Mahmoud-Emad
0e1450b5db chore: add debug prints and perform code cleanup
- Add extensive debug prints for troubleshooting
- Comment out docusaurus build/dev action logic
- Rename gittools parameters for clarity (reset/pull)
- Apply consistent formatting to function calls
- Remove unused imports in playbook include module
2025-08-12 13:37:01 +03:00
f8734a7e9f .. 2025-08-12 11:07:09 +02:00
c05ec6be7f ... 2025-08-12 11:03:49 +02:00
8677d177cb ... 2025-08-12 11:02:21 +02:00
dd37eeaa29 ... 2025-08-12 10:58:53 +02:00
d5753ee794 replace 2025-08-12 10:39:18 +02:00
6b46b3dbaa ... 2025-08-12 10:36:26 +02:00
4cd5b51085 ... 2025-08-12 10:33:29 +02:00
0a7851b920 ... 2025-08-12 09:41:50 +02:00
a0fdaf395e ... 2025-08-12 09:33:53 +02:00
2c5a2ace17 ... 2025-08-11 22:34:23 +02:00
965a2bebb7 ... 2025-08-11 22:12:44 +02:00
2c08ee8687 to compare 2025-08-11 21:41:38 +02:00
e105dd73b5 Merge branch 'development_fix_docusaurus_include' into development
* development_fix_docusaurus_include:
  refactor: Rework playbook include and site import logic
2025-08-11 21:26:49 +02:00
f5dfe8c0af Merge branch 'fix-issue-104' into development
* fix-issue-104:
  Fix issue #104: Fix all biztools examples to use playbook.new()
  Fix issue #104: Add fixed examples and solution documentation
  Fix issue #104: Add notworking.md documenting biztools examples test results

# Conflicts:
#	examples/biztools/notworking.md
2025-08-11 21:26:18 +02:00
ac97e9e7bc Merge branch 'copilot/fix-104' into development
* copilot/fix-104:
  Complete testing of all biztools examples - all 11 scripts are non-functional
  Initial plan
2025-08-11 21:25:57 +02:00
Mahmoud-Emad
beae2cef82 refactor: Rework playbook include and site import logic
- Replace manual script concatenation with playbook include handling
- Preserve site configuration (imports, menu) during generation
- Add support for copying static files from imported content
- Handle static assets from sibling `ebooksall` directories
- Fix import copy logic to not delete destination before copying
2025-08-11 21:53:24 +03:00
2b23771056 ... 2025-08-11 16:38:54 +02:00
19632b4b4b ... 2025-08-11 15:32:12 +02:00
31c033300a Merge branch 'development' of github.com:freeflowuniverse/herolib into development 2025-08-11 11:51:54 +02:00
ca4127319d ... 2025-08-11 11:51:51 +02:00
openhands
d3d8f0d0f1 ... 2025-08-10 03:50:00 +00:00
openhands
2968e4dddc Fix issue #104: Fix all biztools examples to use playbook.new() 2025-08-09 20:08:51 +00:00
copilot-swe-agent[bot]
30c7951058 Complete testing of all biztools examples - all 11 scripts are non-functional
Co-authored-by: despiegk <6021844+despiegk@users.noreply.github.com>
2025-08-09 20:01:58 +00:00
openhands
af63e266d8 Fix issue #104: Add fixed examples and solution documentation 2025-08-09 20:01:37 +00:00
openhands
5d1e3d416e Fix issue #104: Add notworking.md documenting biztools examples test results 2025-08-09 19:57:37 +00:00
copilot-swe-agent[bot]
dd9dc59485 Initial plan 2025-08-09 19:51:51 +00:00
b473630ceb ... 2025-08-09 06:16:49 +02:00
a34b8b70ba ... 2025-08-08 21:36:46 +02:00
fd195f0824 ... 2025-08-08 17:51:57 +02:00
a727d19281 ... 2025-08-08 17:13:33 +02:00
52c88bccb5 bump version to 1.0.28 2025-08-08 17:02:05 +02:00
85cb868bff ... 2025-08-08 17:01:27 +02:00
4339220b42 bump version to 1.0.28 2025-08-08 17:01:11 +02:00
2732 changed files with 196723 additions and 67218 deletions

32
.github/workflows/README.md vendored Normal file
View File

@@ -0,0 +1,32 @@
# Building Hero for release
Generally speaking, our scripts and docs for building hero produce non portable binaries for Linux. While that's fine for development purposes, statically linked binaries are much more convenient for releases and distribution.
The release workflow here creates a static binary for Linux using an Alpine container. A few notes follow about how that's done.
## Static builds in vlang
Since V compiles to C in our case, we are really concerned with how to produce static C builds. The V project provides [some guidance](https://github.com/vlang/v?tab=readme-ov-file#docker-with-alpinemusl) on using an Alpine container and passing `-cflags -static` to the V compiler.
That's fine for some projects. Hero has a dependency on the `libpq` C library for Postgres functionality, however, and this creates a complication.
## Static linking libpq
In order to create a static build of hero on Alpine, we need to install some additional packages:
* openssl-libs-static
* postgresql-dev
The full `apk` command to prepare the container for building looks like this:
```bash
apk add --no-cache bash git build-base openssl-dev libpq-dev postgresql-dev openssl-libs-static
```
Then we also need to instruct the C compiler to link against the Postgres static shared libraries. Here's the build command:
```bash
v -w -d use_openssl -enable-globals -cc gcc -cflags -static -ldflags "-lpgcommon_shlib -lpgport_shlib" cli/hero.v
```
Note that gcc is also the preferred compiler for static builds.

View File

@@ -27,7 +27,7 @@ jobs:
uses: actions/checkout@v4
- name: Setup Vlang
run: ./install_v.sh
run: ./scripts/install_v.sh
- name: Generate documentation
run: |

View File

@@ -5,70 +5,100 @@ permissions:
on:
push:
tags:
- "*"
workflow_dispatch:
jobs:
build:
timeout-minutes: 60
if: startsWith(github.ref, 'refs/tags/')
strategy:
fail-fast: false
matrix:
include:
- target: x86_64-unknown-linux-musl
- target: x86_64-linux
os: ubuntu-latest
short-name: linux-i64
- target: aarch64-unknown-linux-musl
os: ubuntu-latest
short-name: linux-arm64
- target: aarch64-linux
os: ubuntu-24.04-arm
- target: aarch64-apple-darwin
os: macos-latest
short-name: macos-arm64
- target: x86_64-apple-darwin
os: macos-13
short-name: macos-i64
# - target: x86_64-apple-darwin
# os: macos-13
runs-on: ${{ matrix.os }}
container: ${{ matrix.container }}
steps:
- run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event."
- run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!"
- run: echo "🔎 The name of your branch is ${{ github.ref_name }} and your repository is ${{ github.repository }}."
- name: Check out repository code
- name: Checkout code
uses: actions/checkout@v4
- name: Setup V & Herolib
id: setup
run: ./install_v.sh --herolib
shell: bash
run: |
git clone https://github.com/vlang/v
cd v
make
./v symlink
cd -
mkdir -p ~/.vmodules/incubaid
ln -s $(pwd)/lib ~/.vmodules/incubaid/herolib
echo "Herolib symlink created to $(pwd)/lib"
timeout-minutes: 10
- name: Do all the basic tests
timeout-minutes: 25
run: ./test_basic.vsh
# For Linux, we build a static binary linked against musl on Alpine. For
# static linking, gcc is preferred
- name: Build Hero
timeout-minutes: 15
run: |
set -e
v -w -d use_openssl -enable-globals cli/hero.v -o cli/hero-${{ matrix.target }}
set -ex
if [ "${{ runner.os }}" = "Linux" ]; then
# Build for musl using Alpine in Docker
docker run --rm \
-v ${{ github.workspace }}/lib:/root/.vmodules/incubaid/herolib \
-v ${{ github.workspace }}:/herolib \
-w /herolib \
alpine:3.22 \
sh -c '
set -ex
apk add --no-cache bash git build-base openssl-dev libpq-dev postgresql-dev openssl-libs-static
cd v
make clean
make
./v symlink
cd ..
v -w -d use_openssl -enable-globals -cc gcc -cflags -static -ldflags "-lpgcommon_shlib -lpgport_shlib" cli/hero.v -o cli/hero-${{ matrix.target }}-musl
'
else
v -w -d use_openssl -enable-globals -cc clang cli/hero.v -o cli/hero-${{ matrix.target }}
fi
- name: Upload musl binary
if: runner.os == 'Linux'
uses: actions/upload-artifact@v4
with:
name: hero-${{ matrix.target }}-musl
path: cli/hero-${{ matrix.target }}-musl
- name: Upload
if: runner.os != 'Linux'
uses: actions/upload-artifact@v4
with:
name: hero-${{ matrix.target }}
path: cli/hero-${{ matrix.target }}
path: cli/hero-${{ matrix.target }}
release_hero:
needs: build
runs-on: ubuntu-latest
permissions:
contents: write
if: startsWith(github.ref, 'refs/tags/')
steps:
- name: Check out repository code
uses: actions/checkout@v4
- name: Download Artifacts
uses: actions/download-artifact@v4
with:

View File

@@ -5,28 +5,34 @@ permissions:
on:
push:
branches:
- "**"
workflow_dispatch:
jobs:
build:
strategy:
matrix:
include:
- target: x86_64-unknown-linux-musl
os: ubuntu-latest
short-name: linux-i64
runs-on: ${{ matrix.os }}
runs-on: ubuntu-latest
steps:
- run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event."
- run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!"
- run: echo "🔎 The name of your branch is ${{ github.ref_name }} and your repository is ${{ github.repository }}."
- name: Check out repository code
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Setup V & Herolib
run: ./install_v.sh --herolib
- name: Setup V
run: |
# Updating man-db takes a long time on every run. We don't need it
sudo apt-get remove -y --purge man-db
./scripts/install_v.sh
- name: Setup Herolib from current branch
run: |
# Create necessary directories
mkdir -p ~/.vmodules/incubaid
# Create symlink to current code
ln -s $(pwd)/lib ~/.vmodules/incubaid/herolib
echo "Herolib symlink created to $(pwd)/lib"
- name: Do all the basic tests
run: ./test_basic.vsh

9
.gitignore vendored
View File

@@ -11,6 +11,7 @@ __pycache__/
*dSYM/
.vmodules/
.vscode
.dylib
_docs/
vls.*
vls.log
@@ -48,9 +49,13 @@ compile_summary.log
.summary_lock
.aider*
*.dylib
server
HTTP_REST_MCP_DEMO.md
MCP_HTTP_REST_IMPLEMENTATION_PLAN.md
.roo
.kilocode
.continue
.continue
tmux_logger
release
install_herolib
doc
priv_key.bin

2
.qwen/QWEN.md Normal file
View File

@@ -0,0 +1,2 @@
@../aiprompts/vlang_herolib_core.md

52
.qwen/agents/compiler.md Normal file
View File

@@ -0,0 +1,52 @@
---
name: compiler
description: Use this agent when you need to verify V code compilation using vrun, locate files, handle compilation errors, and assist with basic code fixes within the same directory.
color: Automatic Color
---
You are a V Compiler Assistant specialized in verifying V code compilation using the vrun command. Your responsibilities include:
1. File Location:
- First, check if the specified file exists at the given path
- If not found, search for it in the current directory
- If still not found, inform the user clearly about the missing file
2. Compilation Verification:
- Use the vrun command to check compilation: `vrun filepath`. DONT USE v run .. or any other, its vrun ...
- This will compile the file and report any issues without executing it
3. Error Handling:
- If compilation succeeds but warns about missing main function:
* This is expected behavior when using vrun for compilation checking
* Do not take any action on this warning
* Simply note that this is normal for vrun usage
4. Code Fixing:
- If there are compilation errors that prevent successful compilation:
* Fix them to make compilation work
* You can ONLY edit files in the same directory as the file being checked
* Do NOT modify files outside this directory
5. Escalation:
- If you encounter issues that you cannot resolve:
* Warn the user about the problem
* Ask the user what action to take next
6. User Communication:
- Always provide clear, actionable feedback
- Explain what you're doing and why
- When asking for user input, provide context about the issue
Follow these steps in order:
1. Locate the specified file
2. Run vrun on the file
3. Analyze the output
4. Fix compilation errors if possible (within directory constraints)
5. Report results to the user
6. Escalate complex issues to the user
Remember:
- vrun is used for compilation checking only, not execution
- Missing main function warnings are normal and expected
- You can only modify files in the directory of the target file
- Always ask the user before taking action on complex issues

View File

@@ -0,0 +1,67 @@
---
name: struct-validator
description: Use this agent when you need to validate struct definitions in V files for proper serialization (dump/load) of all properties and subproperties, ensure consistency, and generate or fix tests if changes are made. The agent checks for completeness of serialization methods, verifies consistency, and ensures the file compiles correctly.
color: Automatic Color
---
You are a Struct Validation Agent specialized in ensuring V struct definitions are properly implemented for serialization and testing.
## Core Responsibilities
1. **File Location & Validation**
- Locate the specified struct file in the given directory
- If not found, raise an error and ask the user for clarification
2. **Struct Serialization Check**
- Read the file content into your prompt
- Identify all struct definitions
- For each struct:
- Verify that `dump()` and `load()` methods are implemented
- Ensure all properties (including nested complex types) are handled in serialization
- Check for consistency between the struct definition and its serialization methods
3. **Compilation Verification**
- After validation/modification, compile the file using our 'compiler' agent
4. **Test Generation/Correction**
- Only if changes were made to the file:
- Call the `test-generator` agent to create or fix tests for the struct
- Ensure tests validate all properties and subproperties serialization
## Behavioral Parameters
- **Proactive Error Handling**: If a struct lacks proper serialization methods or has inconsistencies, modify the code to implement them correctly
- **User Interaction**: If the file is not found or ambiguous, ask the user for clarification
- **Compilation Check**: Always verify that the file compiles after any modifications
- **Test Generation**: Only generate or fix tests if the file was changed during validation
## Workflow
1. **Locate File**
- Search for the struct file in the specified directory
- If not found, raise an error and ask the user for the correct path
2. **Read & Analyze**
- Load the file content into your prompt
- Parse struct definitions and their methods
3. **Validate Serialization**
- Check `dump()` and `load()` methods for completeness
- Ensure all properties (including nested objects) are serialized
- Report any inconsistencies found
4. **Compile Check**
- using our `compiler` agent
- If errors exist, report and attempt to fix them
5. **Test Generation (Conditional)**
- If changes were made:
- Call the `test-generator` agent to create or fix tests
- Ensure tests cover all serialization aspects
## Output Format
- Clearly indicate whether the file was found
- List any serialization issues and how they were fixed
- Report compilation status
- Mention if tests were generated or modified

52
.qwen/agents/tester.md Normal file
View File

@@ -0,0 +1,52 @@
---
name: tester
description: Use this agent when you need to execute a V test file ending with _test.v within the current directory. The agent will look for the specified file, warn the user if not found, and ask for another file. It will execute the test using vtest, check for compile or assert issues, and attempt to fix them without leaving the current directory. If the issue is caused by code outside the directory, it will ask the user for further instructions.
color: Automatic Color
---
You are a test execution agent specialized in running and troubleshooting V test files ending with _test.v within a confined directory scope.
## Core Responsibilities:
- Locate the specified test file within the current directory.
- Execute the test file using the `vtest` command.
- Analyze the output for compile errors or assertion failures.
- Attempt to fix issues originating within the current directory.
- Prompt the user for guidance when issues stem from code outside the directory.
## Behavioral Boundaries:
- Never navigate or modify files outside the current directory.
- Always verify the file ends with _test.v before execution.
- If the file is not found, warn the user and request an alternative file.
- Do not attempt fixes for external dependencies or code.
## Operational Workflow:
1. **File Search**: Look for the specified file in the current directory.
- If the file is not found:
- Warn the user: "File '{filename}' not found in the current directory."
- Ask: "Please provide another file name to test."
2. **Test Execution**: Run the test using `vtest`.
```bash
vtest {filename}
```
3. **Output Analysis**:
- **Compile Issues**:
- Identify the source of the error.
- If the error originates from code within the current directory, attempt to fix it.
- If the error is due to external code or dependencies, inform the user and ask for instructions.
- **Assertion Failures**:
- Locate the failing assertion.
- If the issue is within the current directory's code, attempt to resolve it.
- If the issue involves external code, inform the user and seek guidance.
4. **Self-Verification**:
- After any fix attempt, re-run the test to confirm resolution.
- Report the final outcome clearly to the user.
## Best Practices:
- Maintain strict directory confinement to ensure security and reliability.
- Prioritize user feedback when external dependencies are involved.
- Use precise error reporting to aid in troubleshooting.
- Ensure all fixes are minimal and targeted to avoid introducing new issues.

View File

@@ -0,0 +1,71 @@
---
name: testgenerator
description: Use this agent when you need to analyze a given source file, generate or update its corresponding test file, and ensure the test file executes correctly by leveraging the testexecutor subagent.
color: Automatic Color
---
You are an expert Vlang test generation agent with deep knowledge of Vlang testing conventions and the Herolib framework. Your primary responsibility is to analyze a given Vlang source file, generate or update its corresponding test file, and ensure the test file executes correctly.
## Core Responsibilities
1. **File Analysis**:
- Locate the specified source file in the current directory.
- If the file is not found, prompt the user with a clear error message.
- Read and parse the source file to identify public methods (functions prefixed with `pub`).
2. **Test File Management**:
- Determine the appropriate test file name using the pattern: `filename_test.v`, where `filename` is the base name of the source file.
- If the test file does not exist, generate a new one.
- If the test file exists, read and analyze its content to ensure it aligns with the source file's public methods.
- Do not look for test files outside of this dir.
3. **Test Code Generation**:
- Generate test cases exclusively for public methods found in the source file.
- Ensure tests are concise and relevant, avoiding over-engineering or exhaustive edge case coverage.
- Write the test code to the corresponding test file.
4. **Test Execution and Validation**:
- Use the `testexecutor` subagent to run the test file.
- If the test fails, analyze the error output, modify the test file to fix the issue, and re-execute.
- Repeat the execution and fixing process until the test file runs successfully.
## Behavioral Boundaries
- **Focus Scope**: Only test public methods. Do not test private functions or generate excessive test cases.
- **File Handling**: Always ensure the test file follows the naming convention `filename_test.v`.
- **Error Handling**: If the source file is not found, clearly inform the user. If tests fail, iteratively fix them using feedback from the `testexecutor`.
- **Idempotency**: If the test file already exists, do not overwrite it entirely. Only update or add missing test cases.
- **Execution**: Use the `vtest` command for running tests, as specified in Herolib guidelines.
## Workflow Steps
1. **Receive Input**: Accept the source file name as an argument.
2. **Locate File**: Check if the file exists in the current directory. If not, notify the user.
3. **Parse Source**: Read the file and extract all public methods.
4. **Check Test File**:
- Derive the test file name: `filename_test.v`.
- If it does not exist, create it with basic test scaffolding.
- If it exists, read its content to understand current test coverage.
5. **Generate/Update Tests**:
- Write or update test cases for each public method.
- Ensure tests are minimal and focused.
6. **Execute Tests**:
- Use the `testexecutor` agent to run the test file.
- If execution fails, analyze the output, fix the test file, and re-execute.
- Continue until tests pass or a critical error is encountered.
7. **Report Status**: Once tests pass, report success. If issues persist, provide a detailed error summary.
## Output Format
- Always provide a clear status update after each test execution.
- If tests are generated or modified, briefly describe what was added or changed.
- If errors occur, explain the issue and the steps taken to resolve it.
- If the source file is not found, provide a user-friendly error message.
## Example Usage
- **Context**: User wants to generate tests for `calculator.v`.
- **Action**: Check if `calculator.v` exists.
- **Action**: Create or update `calculator_test.v` with tests for public methods.
- **Action**: Use `testexecutor` to run `calculator_test.v`.
- **Action**: If tests fail, fix them iteratively until they pass.

View File

@@ -24,7 +24,7 @@ Thank you for your interest in contributing to Herolib! This document provides g
For developers, you can use the automated installation script:
```bash
curl 'https://raw.githubusercontent.com/freeflowuniverse/herolib/refs/heads/development/install_v.sh' > /tmp/install_v.sh
curl 'https://raw.githubusercontent.com/incubaid/herolib/refs/heads/development/scripts/install_v.sh' > /tmp/install_v.sh
bash /tmp/install_v.sh --analyzer --herolib
# IMPORTANT: Start a new shell after installation for paths to be set correctly
```
@@ -32,9 +32,9 @@ 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
git clone git@github.com:freeflowuniverse/herolib.git
mkdir -p ~/code/github/incubaid
cd ~/code/github/incubaid
git clone git@github.com:incubaid/herolib.git
cd herolib
# checkout development branch for most recent changes
git checkout development
@@ -63,6 +63,7 @@ For new features or bug fixes, create a branch from `development` with a descrip
### Making Changes
1. Create a new branch from `development`:
```bash
git checkout development
git pull
@@ -72,6 +73,7 @@ For new features or bug fixes, create a branch from `development` with a descrip
2. Make your changes, following the code guidelines.
3. Run tests to ensure your changes don't break existing functionality:
```bash
./test_basic.vsh
```
@@ -87,10 +89,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.
@@ -98,6 +100,7 @@ The test script (`test_basic.vsh`) manages test execution and caching to optimiz
### Pull Requests
1. Push your branch to the repository:
```bash
git push origin feature/your-feature-name
```
@@ -125,6 +128,7 @@ The repository uses GitHub Actions for continuous integration and deployment:
### 1. Testing Workflow (`test.yml`)
This workflow runs on every push and pull request to ensure code quality:
- Sets up V and Herolib
- Runs all basic tests using `test_basic.vsh`
@@ -133,6 +137,7 @@ All tests must pass before a PR can be merged to the `development` branch.
### 2. Hero Build Workflow (`hero_build.yml`)
This workflow builds the Hero tool for multiple platforms when a new tag is created:
- Builds for Linux (x86_64, aarch64) and macOS (x86_64, aarch64)
- Runs all basic tests
- Creates GitHub releases with the built binaries
@@ -140,6 +145,7 @@ This workflow builds the Hero tool for multiple platforms when a new tag is crea
### 3. Documentation Workflow (`documentation.yml`)
This workflow automatically updates the documentation on GitHub Pages when changes are pushed to the `development` branch:
- Generates documentation using `doc.vsh`
- Deploys the documentation to GitHub Pages
@@ -148,11 +154,11 @@ 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
```
The documentation is automatically published to [https://freeflowuniverse.github.io/herolib/](https://freeflowuniverse.github.io/herolib/) when changes are pushed to the `development` branch.
The documentation is automatically published to [https://incubaid.github.io/herolib/](https://incubaid.github.io/herolib/) when changes are pushed to the `development` branch.
## Troubleshooting
@@ -168,6 +174,7 @@ In file included from /Users/timurgordon/code/github/vlang/v/thirdparty/cJSON/cJ
This is caused by incompatibility between TCC and the half precision math functions in the macOS SDK. To fix this issue:
1. Open the math.h file:
```bash
sudo nano /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/math.h
```
@@ -178,6 +185,6 @@ For more details, see the [README.md](README.md) troubleshooting section.
## Additional Resources
- [Herolib Documentation](https://freeflowuniverse.github.io/herolib/)
- [Cookbook Examples](https://github.com/freeflowuniverse/herolib/tree/development/cookbook)
- [Herolib Documentation](https://incubaid.github.io/herolib/)
- [Cookbook Examples](https://github.com/incubaid/herolib/tree/development/cookbook)
- [AI Prompts](aiprompts/starter/0_start_here.md)

View File

@@ -2,10 +2,10 @@
Herolib is an opinionated library primarily used by ThreeFold to automate cloud environments. It provides a comprehensive set of tools and utilities for cloud automation, git operations, documentation building, and more.
[![Build on Linux & Run tests](https://github.com/freeflowuniverse/herolib/actions/workflows/test.yml/badge.svg)](https://github.com/freeflowuniverse/herolib/actions/workflows/test.yml)
[![Deploy Documentation to Pages](https://github.com/freeflowuniverse/herolib/actions/workflows/documentation.yml/badge.svg)](https://github.com/freeflowuniverse/herolib/actions/workflows/documentation.yml)
[![Build on Linux & Run tests](https://github.com/incubaid/herolib/actions/workflows/test.yml/badge.svg)](https://github.com/incubaid/herolib/actions/workflows/test.yml)
[![Deploy Documentation to Pages](https://github.com/incubaid/herolib/actions/workflows/documentation.yml/badge.svg)](https://github.com/incubaid/herolib/actions/workflows/documentation.yml)
> [Complete Documentation](https://freeflowuniverse.github.io/herolib/)
> [Complete Documentation](https://incubaid.github.io/herolib/)
## Installation
@@ -14,21 +14,18 @@ Herolib is an opinionated library primarily used by ThreeFold to automate cloud
The Hero tool can be installed with a single command:
```bash
curl https://raw.githubusercontent.com/freeflowuniverse/herolib/refs/heads/development/install_hero.sh > /tmp/install_hero.sh
bash /tmp/install_hero.sh
#do not forget to do the following this makes sure vtest and vrun exists
bash install_herolib.vsh
curl https://raw.githubusercontent.com/incubaid/herolib/refs/heads/development/scripts/install_hero.sh | bash
```
Hero will be installed in:
- `/usr/local/bin` for Linux
- `~/hero/bin` for macOS
After installation on macOS, you may need to:
After installation on macOS, you may need to do source see below or restart your terminal to ensure the `hero` command is available:
```bash
source ~/.zprofile
# Or copy to system bin directory
cp ~/hero/bin/hero /usr/local/bin
```
The Hero tool can be used to work with git, build documentation, interact with Hero AI, and more.
@@ -38,9 +35,15 @@ The Hero tool can be used to work with git, build documentation, interact with H
For development purposes, use the automated installation script:
```bash
curl 'https://raw.githubusercontent.com/freeflowuniverse/herolib/refs/heads/development/install_v.sh' > /tmp/install_v.sh
curl 'https://raw.githubusercontent.com/incubaid/herolib/refs/heads/development/scripts/install_v.sh' > /tmp/install_v.sh
bash /tmp/install_v.sh --analyzer --herolib
#do not forget to do the following this makes sure vtest and vrun exists
cd ~/code/github/incubaid/herolib/scripts
v install_herolib.vsh
# IMPORTANT: Start a new shell after installation for paths to be set correctly
```
#### Installation Options
@@ -48,7 +51,7 @@ bash /tmp/install_v.sh --analyzer --herolib
```
V & HeroLib Installer Script
Usage: ~/code/github/freeflowuniverse/herolib/install_v.sh [options]
Usage: ~/code/github/incubaid/herolib/scripts/install_v.sh [options]
Options:
-h, --help Show this help message
@@ -58,12 +61,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/scripts/install_v.sh
~/code/github/incubaid/herolib/scripts/install_v.sh --reset
~/code/github/incubaid/herolib/scripts/install_v.sh --remove
~/code/github/incubaid/herolib/scripts/install_v.sh --analyzer
~/code/github/incubaid/herolib/scripts/install_v.sh --herolib
~/code/github/incubaid/herolib/scripts/install_v.sh --reset --analyzer # Fresh install of both
```
## Features
@@ -72,15 +75,16 @@ Herolib provides a wide range of functionality:
- Cloud automation tools
- Git operations and management
### Offline Mode for Git Operations
Herolib now supports an `offline` mode for Git operations, which prevents automatic fetching from remote repositories. This can be useful in environments with limited or no internet connectivity, or when you want to avoid network calls during development or testing.
To enable offline mode:
- **Via `GitStructureConfig`**: Set the `offline` field to `true` in the `GitStructureConfig` struct.
- **Via `GitStructureArgsNew`**: When creating a new `GitStructure` instance using `gittools.new()`, set the `offline` parameter to `true`.
- **Via Environment Variable**: Set the `OFFLINE` environment variable to any value (e.g., `export OFFLINE=true`).
- **Via `GitStructureConfig`**: Set the `offline` field to `true` in the `GitStructureConfig` struct.
- **Via `GitStructureArgsNew`**: When creating a new `GitStructure` instance using `gittools.new()`, set the `offline` parameter to `true`.
- **Via Environment Variable**: Set the `OFFLINE` environment variable to any value (e.g., `export OFFLINE=true`).
When offline mode is active, `git fetch --all` operations will be skipped, and a debug message "fetch skipped (offline)" will be printed.
- Documentation building
@@ -88,7 +92,7 @@ Herolib provides a wide range of functionality:
- System management utilities
- And much more
Check the [cookbook](https://github.com/freeflowuniverse/herolib/tree/development/cookbook) for examples and use cases.
Check the [cookbook](https://github.com/incubaid/herolib/tree/development/cookbook) for examples and use cases.
## Testing
@@ -96,13 +100,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.
@@ -131,11 +135,13 @@ In file included from /Users/timurgordon/code/github/vlang/v/thirdparty/cJSON/cJ
This is caused by incompatibility between TCC and the half precision math functions in the macOS SDK. To fix this issue:
1. Open the math.h file:
```bash
sudo nano /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/math.h
```
2. Comment out the following lines (around line 612-626):
```c
/* half precision math functions */
// extern _Float16 __fabsf16(_Float16) __API_AVAILABLE(macos(15.0), ios(18.0), watchos(11.0), tvos(18.0));
@@ -157,8 +163,8 @@ This is caused by incompatibility between TCC and the half precision math functi
## Additional Resources
- [Complete Documentation](https://freeflowuniverse.github.io/herolib/)
- [Cookbook Examples](https://github.com/freeflowuniverse/herolib/tree/development/cookbook)
- [Complete Documentation](https://incubaid.github.io/herolib/)
- [Cookbook Examples](https://github.com/incubaid/herolib/tree/development/cookbook)
- [AI Prompts](aiprompts/starter/0_start_here.md)
## Generating Documentation
@@ -166,6 +172,6 @@ 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
```

View File

@@ -0,0 +1,19 @@
#!/bin/bash
# Herolib Web Server Installation Script
# This script sets up the necessary environment for the Flask web server.
set -e # Exit on any error
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Script directory
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
/workspace/herolib/scripts/install_v.sh

77
aiprompts/README.md Normal file
View File

@@ -0,0 +1,77 @@
# HeroLib AI Prompts (`aiprompts/`)
This directory contains AI-oriented instructions and manuals for working with the Hero tool and the `herolib` codebase.
It is the **entry point for AI agents** that generate or modify code/docs in this repository.
## Scope
- **Global rules for AI and V/Hero usage**
See:
- `herolib_start_here.md`
- `vlang_herolib_core.md`
- **Herolib core modules**
See:
- `herolib_core/` (core HeroLib modules)
- `herolib_advanced/` (advanced topics)
- **Docusaurus & Site module (Hero docs)**
See:
- `docusaurus/docusaurus_ebook_manual.md`
- `lib/web/docusaurus/README.md` (authoritative module doc)
- `lib/web/site/ai_instructions.md` and `lib/web/site/readme.md`
- **HeroModels / HeroDB**
See:
- `ai_instructions_hero_models.md`
- `heromodel_instruct.md`
- **V language & web server docs** (upstream-style, mostly language-level)
See:
- `v_core/`, `v_advanced/`
- `v_veb_webserver/`
## Sources of Truth
For any domain, **code and module-level docs are authoritative**:
- Core install & usage: `herolib/README.md`, scripts under `scripts/`
- Site module: `lib/web/site/ai_instructions.md`, `lib/web/site/readme.md`
- Docusaurus module: `lib/web/docusaurus/README.md`, `lib/web/docusaurus/*.v`
- DocTree client: `lib/data/doctree/client/README.md`
- HeroModels: `lib/hero/heromodels/*.v` + tests
`aiprompts/` files **must not contradict** these. When in doubt, follow the code / module docs first and treat prompts as guidance.
## Directory Overview
- `herolib_start_here.md` / `vlang_herolib_core.md`
Global AI rules and V/Hero basics.
- `herolib_core/` & `herolib_advanced/`
Per-module instructions for core/advanced HeroLib features.
- `docusaurus/`
AI manual for building Hero docs/ebooks with the Docusaurus + Site + DocTree pipeline.
- `instructions/`
Active, higher-level instructions (e.g. HeroDB base filesystem).
- `instructions_archive/`
**Legacy / historical** prompt material. See `instructions_archive/README.md`.
- `todo/`
Meta design/refactor notes (not up-to-date instructions for normal usage).
- `v_core/`, `v_advanced/`, `v_veb_webserver/`
V language and web framework references used when generating V code.
- `bizmodel/`, `unpolly/`, `doctree/`, `documentor/`
Domain-specific or feature-specific instructions.
## How to Treat Legacy Material
- Content under `instructions_archive/` is **kept for reference** and may describe older flows (e.g. older documentation or prompt pipelines).
Do **not** use it as a primary source for new work unless explicitly requested.
- Some prompts mention **Doctree**; the current default docs pipeline uses **DocTree**. Doctree/`doctreeclient` is an alternative/legacy backend.
## Guidelines for AI Agents
- Always:
- Respect global rules in `herolib_start_here.md` and `vlang_herolib_core.md`.
- Prefer module docs under `lib/` when behavior or parameters differ.
- Avoid modifying generated files (e.g. `*_ .v` or other generated artifacts) as instructed.
- When instructions conflict, resolve as:
1. **Code & module docs in `lib/`**
2. **AI instructions in `aiprompts/`**
3. **Archived docs (`instructions_archive/`) only when explicitly needed**.

19
aiprompts/WARP.md Normal file
View File

@@ -0,0 +1,19 @@
# WARP.md
This file provides guidance to WARP (warp.dev) when working with code in this repository.
## Commands to Use
### Testing
- **Run Tests**: Utilize `vtest ~/code/github/incubaid/herolib/lib/osal/package_test.v` to run specific tests.
## High-Level Architecture
- **Project Structure**: The project is organized into multiple modules located in `lib` and `src` directories. Prioritized compilation and caching strategies are utilized across modules.
- **Script Handling**: Vlang scripts are crucial and should follow instructions from `aiprompts/vlang_herolib_core.md`.
## Special Instructions
- **Documentation Reference**: Always refer to `aiprompts/vlang_herolib_core.md` for essential instructions regarding Vlang and Heroscript code generation and execution.
- **Environment Specifics**: Ensure Redis and other dependencies are configured as per scripts provided in the codebase.

View File

@@ -0,0 +1,305 @@
# HeroDB Model Creation Instructions for AI
## Overview
This document provides clear instructions for AI agents to create new HeroDB models similar to `message.v`.
These models are used to store structured data in Redis using the HeroDB system.
The `message.v` example can be found in `lib/hero/heromodels/message.v`.
## Key Concepts
- Models must implement serialization/deserialization using the `encoder` module
- Models inherit from the `Base` struct which provides common fields
- The database uses a factory pattern for model access
## File Structure
Create a new file in `lib/hero/heromodels/` with the model name (e.g., `calendar.v`).
## Required Components
### 1. Model Struct Definition
Define your model struct with the following pattern:
```v
@[heap]
pub struct Calendar {
db.Base // Inherit from Base struct
pub mut:
// Add your specific fields here
title string
start_time i64
end_time i64
location string
attendees []string
}
```
### 2. Type Name Method
Implement a method to return the model's type name:
```v
pub fn (self Calendar) type_name() string {
return 'calendar'
}
```
### 3. Serialization (dump) Method
Implement the `dump` method to serialize your struct's fields using the encoder:
```v
pub fn (self Calendar) dump(mut e &encoder.Encoder) ! {
e.add_string(self.title)
e.add_i64(self.start_time)
e.add_i64(self.end_time)
e.add_string(self.location)
e.add_list_string(self.attendees)
}
```
### 4. Deserialization (load) Method
Implement the `load` method to deserialize your struct's fields:
```v
fn (mut self DBCalendar) load(mut o Calendar, mut e &encoder.Decoder) ! {
o.title = e.get_string()!
o.start_time = e.get_i64()!
o.end_time = e.get_i64()!
o.location = e.get_string()!
o.attendees = e.get_list_string()!
}
```
### 5. Model Arguments Struct
Define a struct for creating new instances of your model:
```v
@[params]
pub struct CalendarArg {
pub mut:
title string @[required]
start_time i64
end_time i64
location string
attendees []string
}
```
### 6. Database Wrapper Struct
Create a database wrapper struct for your model:
```v
pub struct DBCalendar {
pub mut:
db &db.DB @[skip; str: skip]
}
```
### 7. Factory Integration
Add your model to the ModelsFactory struct in `factory.v`:
```v
pub struct ModelsFactory {
pub mut:
calendar DBCalendar
// ... other models
}
```
And initialize it in the `new()` function:
```v
pub fn new() !ModelsFactory {
mut mydb := db.new()!
return ModelsFactory{
messages: DBCalendar{
db: &mydb
}
// ... initialize other models
}
}
```
## Encoder Methods Reference
Use these methods for serialization/deserialization:
### Encoder (Serialization)
- `e.add_bool(val bool)`
- `e.add_u8(val u8)`
- `e.add_u16(val u16)`
- `e.add_u32(val u32)`
- `e.add_u64(val u64)`
- `e.add_i8(val i8)`
- `e.add_i16(val i16)`
- `e.add_i32(val i32)`
- `e.add_i64(val i64)`
- `e.add_f32(val f32)`
- `e.add_f64(val f64)`
- `e.add_string(val string)`
- `e.add_list_bool(val []bool)`
- `e.add_list_u8(val []u8)`
- `e.add_list_u16(val []u16)`
- `e.add_list_u32(val []u32)`
- `e.add_list_u64(val []u64)`
- `e.add_list_i8(val []i8)`
- `e.add_list_i16(val []i16)`
- `e.add_list_i32(val []i32)`
- `e.add_list_i64(val []i64)`
- `e.add_list_f32(val []f32)`
- `e.add_list_f64(val []f64)`
- `e.add_list_string(val []string)`
### Decoder (Deserialization)
- `e.get_bool()!`
- `e.get_u8()!`
- `e.get_u16()!`
- `e.get_u32()!`
- `e.get_u64()!`
- `e.get_i8()!`
- `e.get_i16()!`
- `e.get_i32()!`
- `e.get_i64()!`
- `e.get_f32()!`
- `e.get_f64()!`
- `e.get_string()!`
- `e.get_list_bool()!`
- `e.get_list_u8()!`
- `e.get_list_u16()!`
- `e.get_list_u32()!`
- `e.get_list_u64()!`
- `e.get_list_i8()!`
- `e.get_list_i16()!`
- `e.get_list_i32()!`
- `e.get_list_i64()!`
- `e.get_list_f32()!`
- `e.get_list_f64()!`
- `e.get_list_string()!`
## CRUD Methods Implementation
### Create New Instance
```v
pub fn (mut self DBCalendar) new(args CalendarArg) !Calendar {
mut o := Calendar{
title: args.title
start_time: args.start_time
end_time: args.end_time
location: args.location
attendees: args.attendees
updated_at: ourtime.now().unix()
}
return o
}
```
### Save to Database
```v
pub fn (mut self DBCalendar) set(o Calendar) !Calendar {
return self.db.set[Calendar](o)!
}
```
### Retrieve from Database
```v
pub fn (mut self DBCalendar) get(id u32) !Calendar {
mut o, data := self.db.get_data[Calendar](id)!
mut e_decoder := encoder.decoder_new(data)
self.load(mut o, mut e_decoder)!
return o
}
```
### Delete from Database
```v
pub fn (mut self DBCalendar) delete(id u32) ! {
self.db.delete[Calendar](id)!
}
```
### Check Existence
```v
pub fn (mut self DBCalendar) exist(id u32) !bool {
return self.db.exists[Calendar](id)!
}
```
### List All Objects
```v
pub fn (mut self DBCalendar) list() ![]Calendar {
return self.db.list[Calendar]()!.map(self.get(it)!)
}
```
## Example Usage Script
Create a `.vsh` script in `examples/hero/heromodels/` to demonstrate usage:
```v
#!/usr/bin/env -S v -n -w -cg -gc none -cc tcc -d use_openssl -enable-globals run
import incubaid.herolib.core.redisclient
import incubaid.herolib.hero.heromodels
mut mydb := heromodels.new()!
// Create a new object
mut o := mydb.calendar.new(
title: 'Meeting'
start_time: 1672531200
end_time: 1672534800
location: 'Conference Room'
attendees: ['john@example.com', 'jane@example.com']
)!
// Save to database
oid := mydb.calendar.set(o)!
println('Created object with ID: ${oid}')
// Retrieve from database
mut o2 := mydb.calendar.get(oid)!
println('Retrieved object: ${o2}')
// List all objects
mut objects := mydb.calendar.list()!
println('All objects: ${objects}')
```
## Best Practices
1. Always inherit from `db.Base` struct
2. Implement all required methods (`type_name`, `dump`, `load`)
3. Use the encoder methods for consistent serialization
4. Handle errors appropriately with `!` or `or` blocks
5. Keep field ordering consistent between `dump` and `load` methods
6. Use snake_case for field names
7. Add `@[required]` attribute to mandatory fields in argument structs
8. Initialize timestamps using `ourtime.now().unix()`
## Implementation Steps Summary
1. Create model struct inheriting from `db.Base`
2. Implement `type_name()` method
3. Implement `dump()` method using encoder
4. Implement `load()` method using decoder
5. Create argument struct with `@[params]` attribute
6. Create database wrapper struct
7. Add model to `ModelsFactory` in `factory.v`
8. Implement CRUD methods
9. Create example usage script
10. Test the implementation with the example script

View File

@@ -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

View File

@@ -1,4 +1,4 @@
# Revenue
# Revenue
```
!!bizmodel.revenue_define bizname:'test' name:'oem1' ...
@@ -21,7 +21,7 @@ cogs stands for cost of goods
- cogs_delay: delay in months between cogs and revenue
- extrapolate: if you want to extrapolate revenue or cogs do extrapolate:1, default is 0
### results in
### results in
follow rows in sheets
@@ -36,16 +36,14 @@ follow rows in sheets
- revenue_item_setup_delay, delay between sell and recognition of sale in months e.g. 1
- revenue_item_monthly, revenue per month for 1 item
- revenue_item_monthly_delay, how many months before monthly revenue starts
- revenue_item_monthly_perc, how much percent of revenue_item_setup will come back over months e.g. 20%
- revenue_item_monthly_perc, how much percent of revenue_item_setup will come back over months e.g. 20%
- cogs_item_setup, cost of good for 1 item at setup
- cogs_item_setup_rev_perc: what is percentage of the revenue which is cogs, e.g. 2%
- cogs_item_monthly, cost of goods for the monthly per 1 item
- cogs_item_monthly_rev_perc: what is percentage of the monthly revenue which is cogs, e.g. 10%
- cogs_item_delay, how many months before cogs starts after sales
### results in
### results in
follow rows in sheets
@@ -62,7 +60,7 @@ follow rows in sheets
```v
import freeflowuniverse.herolib.biz.bizmodel
import incubaid.herolib.biz.bizmodel
import os
heroscript:="
@@ -89,4 +87,4 @@ mut bm:=bizmodel.get("test")!
bm.sheet.pprint()!
```
```

View File

@@ -2,13 +2,38 @@
This manual provides a comprehensive guide on how to leverage HeroLib's Docusaurus integration, Doctree, and HeroScript to create and manage technical ebooks, optimized for AI-driven content generation and project management.
## Quick Start - Recommended Ebook Structure
The recommended directory structure for an ebook:
```
my_ebook/
├── scan.hero # DocTree collection scanning
├── config.hero # Site configuration
├── menus.hero # Navbar and footer configuration
├── include.hero # Docusaurus define and doctree export
├── 1_intro.heroscript # Page definitions (numbered for ordering)
├── 2_concepts.heroscript # More page definitions
└── 3_advanced.heroscript # Additional pages
```
**Running an ebook:**
```bash
# Start development server
hero docs -d -p /path/to/my_ebook
# Build for production
hero docs -p /path/to/my_ebook
```
## 1. Core Concepts
To effectively create ebooks with HeroLib, it's crucial to understand the interplay of three core components:
* **HeroScript**: A concise scripting language used to define the structure, configuration, and content flow of your Docusaurus site. It acts as the declarative interface for the entire process.
* **Docusaurus**: A popular open-source static site generator. HeroLib uses Docusaurus as the underlying framework to render your ebook content into a navigable website.
* **Doctree**: HeroLib's content management system. Doctree organizes your markdown files into "collections" and "pages," allowing for structured content retrieval and reuse across multiple projects.
* **HeroScript**: A concise scripting language used to define the structure, configuration, and content flow of your Docusaurus site. It acts as the declarative interface for the entire process. Files use `.hero` extension for configuration and `.heroscript` for page definitions.
* **Docusaurus**: A popular open-source static site generator. HeroLib uses Docusaurus as the underlying framework to render your ebook content into a navigable website.
* **DocTree**: HeroLib's document collection layer. DocTree scans and exports markdown "collections" and "pages" that Docusaurus consumes.
## 2. Setting Up a Docusaurus Project with HeroLib
@@ -22,18 +47,26 @@ The `docusaurus.define` HeroScript directive configures the global settings for
```heroscript
!!docusaurus.define
name:"my_ebook" // must match the site name from !!site.config
path_build: "/tmp/my_ebook_build"
path_publish: "/tmp/my_ebook_publish"
production: true
update: true
reset: true // clean build dir before building (optional)
install: true // run bun install if needed (optional)
template_update: true // update the Docusaurus template (optional)
doctree_dir: "/tmp/doctree_export" // where DocTree exports collections
use_doctree: true // use DocTree as content backend
```
**Arguments:**
* `path_build` (string, optional): The local path where the Docusaurus site will be built. Defaults to `~/hero/var/docusaurus/build`.
* `path_publish` (string, optional): The local path where the final Docusaurus site will be published (e.g., for deployment). Defaults to `~/hero/var/docusaurus/publish`.
* `production` (boolean, optional): If `true`, the site will be built for production (optimized). Default is `false`.
* `update` (boolean, optional): If `true`, the Docusaurus template and dependencies will be updated. Default is `false`.
* `name` (string, required): The site/factory name. Must match the `name` used in `!!site.config` so Docusaurus can find the corresponding site definition.
* `path_build` (string, optional): The local path where the Docusaurus site will be built. Defaults to `~/hero/var/docusaurus/build`.
* `path_publish` (string, optional): The local path where the final Docusaurus site will be published (e.g., for deployment). Defaults to `~/hero/var/docusaurus/publish`.
* `reset` (boolean, optional): If `true`, clean the build directory before starting.
* `install` (boolean, optional): If `true`, run dependency installation (e.g., `bun install`).
* `template_update` (boolean, optional): If `true`, update the Docusaurus template.
* `doctree_dir` (string, optional): Directory where DocTree exports collections (used by the DocTree client in `lib/data/doctree/client`).
* `use_doctree` (boolean, optional): If `true`, use the DocTree client as the content backend (default behavior).
### 2.2. Adding a Docusaurus Site (`docusaurus.add`)
@@ -53,7 +86,7 @@ The `docusaurus.add` directive defines an individual Docusaurus site (your ebook
```heroscript
!!docusaurus.add
name:"tfgrid_tech_ebook"
git_url:"https://git.threefold.info/tfgrid/docs_tfgrid4/src/branch/main/ebooks/tech"
git_url:"https://git.ourworld.tf/tfgrid/docs_tfgrid4/src/branch/main/ebooks/tech"
git_reset:true // Reset Git repository before pulling
git_pull:true // Pull latest changes
git_root:"/tmp/git_clones" // Optional: specify a root directory for git clones
@@ -61,19 +94,19 @@ The `docusaurus.add` directive defines an individual Docusaurus site (your ebook
**Arguments:**
* `name` (string, optional): A unique name for your Docusaurus site/ebook. Defaults to "main".
* `path` (string, optional): The local file system path to the root of your documentation content (e.g., where your `docs` and `cfg` directories are).
* `git_url` (string, optional): A Git URL to a repository containing your documentation content. HeroLib will clone/pull this repository.
* `git_reset` (boolean, optional): If `true`, the Git repository will be reset to a clean state before pulling. Default is `false`.
* `git_pull` (boolean, optional): If `true`, the Git repository will be pulled to get the latest changes. Default is `false`.
* `git_root` (string, optional): An optional root directory where Git repositories will be cloned.
* `nameshort` (string, optional): A shorter name for the Docusaurus site. Defaults to the value of `name`.
* `path_publish` (string, optional): Overrides the factory's `path_publish` for this specific site.
* `production` (boolean, optional): Overrides the factory's `production` setting for this specific site.
* `watch_changes` (boolean, optional): If `true`, HeroLib will watch for changes in your source `docs` directory and trigger rebuilds. Default is `true`.
* `update` (boolean, optional): If `true`, this specific documentation will be updated. Default is `false`.
* `open` (boolean, optional): If `true`, the Docusaurus site will be opened in your default browser after generation/development server start. Default is `false`.
* `init` (boolean, optional): If `true`, the Docusaurus site will be initialized (e.g., creating missing `docs` directories). Default is `false`.
* `name` (string, optional): A unique name for your Docusaurus site/ebook. Defaults to "main".
* `path` (string, optional): The local file system path to the root of your documentation content (e.g., where your `docs` and `cfg` directories are).
* `git_url` (string, optional): A Git URL to a repository containing your documentation content. HeroLib will clone/pull this repository.
* `git_reset` (boolean, optional): If `true`, the Git repository will be reset to a clean state before pulling. Default is `false`.
* `git_pull` (boolean, optional): If `true`, the Git repository will be pulled to get the latest changes. Default is `false`.
* `git_root` (string, optional): An optional root directory where Git repositories will be cloned.
* `nameshort` (string, optional): A shorter name for the Docusaurus site. Defaults to the value of `name`.
* `path_publish` (string, optional): Overrides the factory's `path_publish` for this specific site.
* `production` (boolean, optional): Overrides the factory's `production` setting for this specific site.
* `watch_changes` (boolean, optional): If `true`, HeroLib will watch for changes in your source `docs` directory and trigger rebuilds. Default is `true`.
* `update` (boolean, optional): If `true`, this specific documentation will be updated. Default is `false`.
* `open` (boolean, optional): If `true`, the Docusaurus site will be opened in your default browser after generation/development server start. Default is `false`.
* `init` (boolean, optional): If `true`, the Docusaurus site will be initialized (e.g., creating missing `docs` directories). Default is `false`.
## 3. Structuring Content with HeroScript and Doctree
@@ -105,22 +138,22 @@ These directives define the fundamental properties and metadata of your Docusaur
**Arguments:**
* **`site.config`**:
* `name` (string, required): Unique identifier for the site.
* `title` (string, optional): Main title of the site. Defaults to "My Documentation Site".
* `description` (string, optional): General site description.
* `tagline` (string, optional): Short tagline for the site.
* `favicon` (string, optional): Path to the favicon. Defaults to "img/favicon.png".
* `image` (string, optional): General site image (e.g., for social media previews). Defaults to "img/tf_graph.png".
* `copyright` (string, optional): Copyright notice. Defaults to "© [Current Year] Example Organization".
* `url` (string, optional): The main URL where the site will be hosted.
* `base_url` (string, optional): The base URL for Docusaurus (e.g., `/` or `/my-ebook/`).
* `url_home` (string, optional): The path to the home page relative to `base_url`.
* **`site.config_meta`**: Overrides for specific SEO metadata.
* `title` (string, optional): Specific title for SEO (e.g., `<meta property="og:title">`).
* `image` (string, optional): Specific image for SEO (e.g., `<meta property="og:image">`).
* `description` (string, optional): Specific description for SEO.
* `keywords` (string, optional): Comma-separated keywords for SEO.
* **`site.config`**:
* `name` (string, required): Unique identifier for the site.
* `title` (string, optional): Main title of the site. Defaults to "My Documentation Site".
* `description` (string, optional): General site description.
* `tagline` (string, optional): Short tagline for the site.
* `favicon` (string, optional): Path to the favicon. Defaults to "img/favicon.png".
* `image` (string, optional): General site image (e.g., for social media previews). Defaults to "img/tf_graph.png".
* `copyright` (string, optional): Copyright notice. Defaults to "© [Current Year] Example Organization".
* `url` (string, optional): The main URL where the site will be hosted.
* `base_url` (string, optional): The base URL for Docusaurus (e.g., `/` or `/my-ebook/`).
* `url_home` (string, optional): The path to the home page relative to `base_url`.
* **`site.config_meta`**: Overrides for specific SEO metadata.
* `title` (string, optional): Specific title for SEO (e.g., `<meta property="og:title">`).
* `image` (string, optional): Specific image for SEO (e.g., `<meta property="og:image">`).
* `description` (string, optional): Specific description for SEO.
* `keywords` (string, optional): Comma-separated keywords for SEO.
### 3.2. Navigation Bar (`site.navbar`, `site.navbar_item`)
@@ -148,16 +181,16 @@ Define the main navigation menu of your Docusaurus site.
**Arguments:**
* **`site.navbar`**:
* `title` (string, optional): Title displayed in the navbar. Defaults to `site.config.title`.
* `logo_alt` (string, optional): Alt text for the logo.
* `logo_src` (string, optional): Path to the light mode logo.
* `logo_src_dark` (string, optional): Path to the dark mode logo.
* **`site.navbar_item`**:
* `label` (string, required): Text displayed for the menu item.
* `href` (string, optional): External URL for the link.
* `to` (string, optional): Internal Docusaurus path (e.g., `/docs/my-page`).
* `position` (string, optional): "left" or "right" for placement in the navbar. Defaults to "right".
* **`site.navbar`**:
* `title` (string, optional): Title displayed in the navbar. Defaults to `site.config.title`.
* `logo_alt` (string, optional): Alt text for the logo.
* `logo_src` (string, optional): Path to the light mode logo.
* `logo_src_dark` (string, optional): Path to the dark mode logo.
* **`site.navbar_item`**:
* `label` (string, required): Text displayed for the menu item.
* `href` (string, optional): External URL for the link.
* `to` (string, optional): Internal Docusaurus path (e.g., `/docs/my-page`).
* `position` (string, optional): "left" or "right" for placement in the navbar. Defaults to "right".
### 3.3. Footer (`site.footer`, `site.footer_item`)
@@ -182,34 +215,34 @@ Configure the footer section of your Docusaurus site.
**Arguments:**
* **`site.footer`**:
* `style` (string, optional): "dark" or "light" style for the footer. Defaults to "dark".
* **`site.footer_item`**:
* `title` (string, required): The title under which this item will be grouped in the footer.
* `label` (string, required): Text displayed for the footer link.
* `href` (string, optional): External URL for the link.
* `to` (string, optional): Internal Docusaurus path.
* **`site.footer`**:
* `style` (string, optional): "dark" or "light" style for the footer. Defaults to "dark".
* **`site.footer_item`**:
* `title` (string, required): The title under which this item will be grouped in the footer.
* `label` (string, required): Text displayed for the footer link.
* `href` (string, optional): External URL for the link.
* `to` (string, optional): Internal Docusaurus path.
### 3.4. Build Destinations (`site.build_dest`, `site.build_dest_dev`)
### 3.4. Publish Destinations (`site.publish`, `site.publish_dev`)
Specify where the built Docusaurus site should be deployed. This typically involves an SSH connection defined elsewhere (e.g., `!!site.ssh_connection`).
**HeroScript Example:**
```heroscript
!!site.build_dest
!!site.publish
ssh_name:"production_server" // Name of a pre-defined SSH connection
path:"/var/www/my-ebook" // Remote path on the server
path:"/var/www/my-ebook" // Remote path on the server
!!site.build_dest_dev
!!site.publish_dev
ssh_name:"dev_server"
path:"/tmp/dev-ebook"
```
**Arguments:**
* `ssh_name` (string, required): The name of the SSH connection to use for deployment.
* `path` (string, required): The destination path on the remote server.
* `ssh_name` (string, required): The name of the SSH connection to use for deployment.
* `path` (string, required): The destination path on the remote server.
### 3.5. Importing External Content (`site.import`)
@@ -219,16 +252,16 @@ This powerful feature allows you to pull markdown content and assets from other
```heroscript
!!site.import
url:'https://git.threefold.info/tfgrid/docs_tfgrid4/src/branch/main/collections/cloud_reinvented'
url:'https://git.ourworld.tf/tfgrid/docs_tfgrid4/src/branch/main/collections/cloud_reinvented'
dest:'cloud_reinvented' // Destination subdirectory within your Docusaurus docs folder
replace:'NAME:MyName, URGENCY:red' // Optional: comma-separated key:value pairs for text replacement
```
**Arguments:**
* `url` (string, required): The Git URL of the repository or specific path within a repository to import.
* `dest` (string, required): The subdirectory within your Docusaurus `docs` folder where the imported content will be placed.
* `replace` (string, optional): A comma-separated string of `KEY:VALUE` pairs. During import, all occurrences of `${KEY}` in the imported content will be replaced with `VALUE`.
* `url` (string, required): The Git URL of the repository or specific path within a repository to import.
* `dest` (string, required): The subdirectory within your Docusaurus `docs` folder where the imported content will be placed.
* `replace` (string, optional): A comma-separated string of `KEY:VALUE` pairs. During import, all occurrences of `${KEY}` in the imported content will be replaced with `VALUE`.
### 3.6. Defining Pages and Categories (`site.page_category`, `site.page`)
@@ -238,47 +271,60 @@ This is where you define the actual content pages and how they are organized int
```heroscript
// Define a category
!!site.page_category path:'introduction' label:"Introduction to Ebook" position:10
!!site.page_category name:'introduction' label:"Introduction to Ebook"
// Define a page within that category, linking to Doctree content
!!site.page path:'introduction' src:"my_doctree_collection:chapter_1_overview"
// Define pages - first page specifies collection, subsequent pages reuse it
!!site.page src:"my_collection:chapter_1_overview"
title:"Chapter 1: Overview"
description:"A brief introduction to the ebook's content."
position:1 // Order within the category
hide_title:true // Hide the title on the page itself
!!site.page src:"chapter_2_basics"
title:"Chapter 2: Basics"
// New category with new collection
!!site.page_category name:'advanced' label:"Advanced Topics"
!!site.page src:"advanced_collection:performance"
title:"Performance Tuning"
hide_title:true
```
**Arguments:**
* **`site.page_category`**:
* `path` (string, required): The path to the category directory within your Docusaurus `docs` folder (e.g., `introduction` will create `docs/introduction/_category_.json`).
* `label` (string, required): The display name for the category in the sidebar.
* `position` (int, optional): The order of the category in the sidebar.
* `sitename` (string, optional): If you have multiple Docusaurus sites defined, specify which site this category belongs to. Defaults to the current site's name.
* **`site.page`**:
* `src` (string, required): **Crucial for Doctree integration.** This specifies the source of the page content in the format `collection_name:page_name`. HeroLib will fetch the markdown content from the specified Doctree collection and page.
* `path` (string, required): The relative path and filename for the generated markdown file within your Docusaurus `docs` folder (e.g., `introduction/chapter_1.md`). If only a directory is provided (e.g., `introduction/`), the `page_name` from `src` will be used as the filename.
* `title` (string, optional): The title of the page. If not provided, HeroLib will attempt to extract it from the markdown content or use the `page_name`.
* `description` (string, optional): A short description for the page, used in frontmatter.
* `position` (int, optional): The order of the page within its category.
* `hide_title` (boolean, optional): If `true`, the title will not be displayed on the page itself.
* `draft` (boolean, optional): If `true`, the page will be marked as a draft and not included in production builds.
* `title_nr` (int, optional): If set, HeroLib will re-number the markdown headings (e.g., `title_nr:3` will make `# Heading` become `### Heading`). Useful for consistent heading levels across imported content.
* **`site.page_category`**:
* `name` (string, required): Category identifier (used internally).
* `label` (string, required): The display name for the category in the sidebar.
* `position` (int, optional): The order of the category in the sidebar (auto-incremented if omitted).
* **`site.page`**:
* `src` (string, required): **Crucial for DocTree/collection integration.** Format: `collection_name:page_name` for the first page, or just `page_name` to reuse the previous collection.
* `title` (string, optional): The title of the page. If not provided, HeroLib extracts it from the markdown `# Heading` or uses the page name.
* `description` (string, optional): A short description for the page, used in frontmatter.
* `hide_title` (boolean, optional): If `true`, the title will not be displayed on the page itself.
* `draft` (boolean, optional): If `true`, the page will be hidden from navigation.
### 3.7. Doctree Integration Details
### 3.7. Collections and DocTree/Doctree Integration
The `site.page` directive's `src` parameter (`collection_name:page_name`) is the bridge to your Doctree content.
The `site.page` directive's `src` parameter (`collection_name:page_name`) is the bridge to your content collections.
**How Doctree Works:**
**Current default: DocTree export**
1. **Collections**: DocTree exports markdown files into collections under an `export_dir` (see `lib/data/doctree/client`).
2. **Export step**: A separate process (DocTree) writes the collections into `doctree_dir` (e.g., `/tmp/doctree_export`), following the `content/` + `meta/` structure.
3. **Docusaurus consumption**: The Docusaurus module uses the DocTree client (`doctree_client`) to resolve `collection_name:page_name` into markdown content and assets when generating docs.
**Alternative: Doctree/`doctreeclient`**
In older setups, or when explicitly configured, Doctree and `doctreeclient` can still be used to provide the same `collection:page` model:
1. **Collections**: Doctree organizes markdown files into logical groups called "collections." A collection is typically a directory containing markdown files and an empty `.collection` file.
2. **Scanning**: You define which collections Doctree should scan using `!!doctree.scan` in a HeroScript file (e.g., `doctree.heroscript`):
1. **Collections**: Doctree organizes markdown files into logical groups called "collections." A collection is typically a directory containing markdown files and an empty `.collection` file.
2. **Scanning**: You define which collections Doctree should scan using `!!doctree.scan` in a HeroScript file (e.g., `doctree.heroscript`).
**Example `doctree.heroscript`:**
```heroscript
!!doctree.scan git_url:"https://git.threefold.info/tfgrid/docs_tfgrid4/src/branch/main/collections"
!!doctree.scan git_url:"https://git.ourworld.tf/tfgrid/docs_tfgrid4/src/branch/main/collections"
```
This will pull the `collections` directory from the specified Git URL and make its contents available to Doctree.
3. **Page Retrieval**: When `site.page` references `src:"my_collection:my_page"`, HeroLib's `doctreeclient` fetches the content of `my_page.md` from the `my_collection` collection that Doctree has scanned.
3. **Page Retrieval**: When `site.page` references `src:"my_collection:my_page"`, the client (`doctree_client` or `doctreeclient`, depending on configuration) fetches the content of `my_page.md` from the `my_collection` collection.
## 4. Building and Developing Your Ebook
@@ -287,12 +333,13 @@ Once your HeroScript configuration is set up, HeroLib provides commands to build
### 4.1. Generating Site Files (`site.generate()`)
The `site.generate()` function (called internally by `build`, `dev`, etc.) performs the core file generation:
* Copies Docusaurus template files.
* Copies your site's `src` and `static` assets.
* Generates Docusaurus configuration JSON files (`main.json`, `navbar.json`, `footer.json`) from your HeroScript `site.config`, `site.navbar`, and `site.footer` directives.
* Copies your source `docs` directory.
* Processes `site.page` and `site.page_category` directives using the `sitegen` module to create the final markdown files and `_category_.json` files in the Docusaurus `docs` directory, fetching content from Doctree.
* Handles `site.import` directives, pulling external content and performing replacements.
* Copies Docusaurus template files.
* Copies your site's `src` and `static` assets.
* Generates Docusaurus configuration JSON files (`main.json`, `navbar.json`, `footer.json`) from your HeroScript `site.config`, `site.navbar`, and `site.footer` directives.
* Copies your source `docs` directory.
* Processes `site.page` and `site.page_category` directives using the `sitegen` module to create the final markdown files and `_category_.json` files in the Docusaurus `docs` directory, fetching content from Doctree.
* Handles `site.import` directives, pulling external content and performing replacements.
### 4.2. Local Development
@@ -305,35 +352,34 @@ can be stored as example_docusaurus.vsh and then used to generate and develop an
```v
#!/usr/bin/env -S v -n -w -gc none -cg -cc tcc -d use_openssl -enable-globals run
import freeflowuniverse.herolib.web.docusaurus
import incubaid.herolib.web.docusaurus
import os
const cfgpath = os.dir(@FILE)
docusaurus.new(
heroscript: '
heroscript: '
// !!docusaurus.define
// path_build: "/tmp/docusaurus_build"
// path_publish: "/tmp/docusaurus_publish"
// !!docusaurus.define
// path_build: "/tmp/docusaurus_build"
// path_publish: "/tmp/docusaurus_publish"
!!docusaurus.add name:"tfgrid_docs"
path:"${cfgpath}"
!!docusaurus.add name:"tfgrid_docs"
path:"${cfgpath}"
!!docusaurus.dev
!!docusaurus.dev
'
'
)!
```
the following script suggest to call it do.vsh and put in directory of where the ebook is
```v
#!/usr/bin/env -S v -n -w -gc none -cg -cc tcc -d use_openssl -enable-globals run
import freeflowuniverse.herolib.web.docusaurus
import incubaid.herolib.web.docusaurus
const cfgpath = os.dir(@FILE) + '/cfg'
@@ -341,4 +387,3 @@ docusaurus.new(heroscript_path:cfgpath)!
```
by just called do.vsh we can execute on the ebook

View File

@@ -13,12 +13,12 @@ The `list` method accepts a `ListArgs` struct to control its behavior:
```v
pub struct ListArgs {
pub mut:
regex []string // A slice of regular expressions to filter files.
recursive bool = true // Whether to list files recursively (default true).
ignoredefault bool = true // Whether to ignore files starting with . and _ (default true).
include_links bool // Whether to include symbolic links in the list.
dirs_only bool // Whether to include only directories in the list.
files_only bool // Whether to include only files in the list.
regex []string // A slice of regular expressions to filter files.
recursive bool = true // Whether to list files recursively (default true).
ignore_default bool = true // Whether to ignore files starting with . and _ (default true).
include_links bool // Whether to include symbolic links in the list.
dirs_only bool // Whether to include only directories in the list.
files_only bool // Whether to include only files in the list.
}
```
@@ -31,7 +31,7 @@ Here are examples demonstrating how to use these advanced filtering options:
You can use regular expressions to filter files based on their names or extensions. The `regex` parameter accepts a slice of strings, where each string is a regex pattern.
```v
import freeflowuniverse.herolib.core.pathlib
import incubaid.herolib.core.pathlib
// Get a directory path
mut dir := pathlib.get('/some/directory')!
@@ -61,7 +61,7 @@ for path_obj in vlang_files.paths {
By default, `list()` is recursive. You can disable recursion to list only items in the current directory.
```v
import freeflowuniverse.herolib.core.pathlib
import incubaid.herolib.core.pathlib
mut dir := pathlib.get('/some/directory')!
@@ -77,16 +77,16 @@ for path_obj in top_level_items.paths {
#### 3. Including or Excluding Hidden Files
The `ignoredefault` parameter controls whether files and directories starting with `.` or `_` are ignored.
The `ignore_default` parameter controls whether files and directories starting with `.` or `_` are ignored.
```v
import freeflowuniverse.herolib.core.pathlib
import incubaid.herolib.core.pathlib
mut dir := pathlib.get('/some/directory')!
// List all files and directories, including hidden ones
mut all_items := dir.list(
ignoredefault: false
ignore_default: false
)!
for path_obj in all_items.paths {
@@ -99,7 +99,7 @@ for path_obj in all_items.paths {
By default, symbolic links are ignored when walking the directory structure. Set `include_links` to `true` to include them.
```v
import freeflowuniverse.herolib.core.pathlib
import incubaid.herolib.core.pathlib
mut dir := pathlib.get('/some/directory')!
@@ -118,7 +118,7 @@ for path_obj in items_with_links.paths {
Use `dirs_only` or `files_only` to restrict the results to only directories or only files.
```v
import freeflowuniverse.herolib.core.pathlib
import incubaid.herolib.core.pathlib
mut dir := pathlib.get('/some/directory')!
@@ -138,4 +138,4 @@ for path_obj in only_dirs.paths {
}
```
By combining these parameters, you can create highly specific and powerful file system listing operations tailored to your needs.
By combining these parameters, you can create highly specific and powerful file system listing operations tailored to your needs.

View File

@@ -4,10 +4,10 @@ The `builder` module in Herolib provides a powerful framework for automating sys
## Key Components
- **`BuilderFactory`**: Responsible for creating and managing `Node` instances.
- **`Node`**: Represents a target system (local or remote). It encapsulates system properties (platform, CPU type, environment variables) and provides methods for interaction.
- **`Executor`**: An interface (implemented by `ExecutorLocal` and `ExecutorSSH`) that handles the actual command execution and file operations on the target system.
- **NodeDB (via `Node.done` map)**: A key-value store within each `Node` for persistent state, caching, and tracking execution history.
- **`BuilderFactory`**: Responsible for creating and managing `Node` instances.
- **`Node`**: Represents a target system (local or remote). It encapsulates system properties (platform, CPU type, environment variables) and provides methods for interaction.
- **`Executor`**: An interface (implemented by `ExecutorLocal` and `ExecutorSSH`) that handles the actual command execution and file operations on the target system.
- **NodeDB (via `Node.done` map)**: A key-value store within each `Node` for persistent state, caching, and tracking execution history.
## Getting Started
@@ -16,7 +16,7 @@ The `builder` module in Herolib provides a powerful framework for automating sys
First, import the `builder` module and create a new `BuilderFactory` instance. Then, create a `Node` object, which can represent either the local machine or a remote server.
```v
import freeflowuniverse.herolib.builder
import incubaid.herolib.builder
// Create a new builder factory
mut b := builder.new()!
@@ -68,7 +68,7 @@ The `Node` object provides methods to execute commands on the target system.
Executes a command and returns its standard output.
```v
import freeflowuniverse.herolib.builder { ExecArgs }
import incubaid.herolib.builder { ExecArgs }
// Execute a command with stdout
result := node.exec(cmd: "ls -la /tmp", stdout: true)!
@@ -101,7 +101,7 @@ node.exec_interactive("bash")!
A more advanced command execution method that supports caching, periodic execution, and temporary script handling.
```v
import freeflowuniverse.herolib.builder { NodeExecCmd }
import incubaid.herolib.builder { NodeExecCmd }
// Execute a command, cache its result for 24 hours (48*3600 seconds)
// and provide a description for logging.
@@ -130,7 +130,7 @@ println(script_output)
Executes a command with retries until it succeeds or a timeout is reached.
```v
import freeflowuniverse.herolib.builder { ExecRetryArgs }
import incubaid.herolib.builder { ExecRetryArgs }
// Try to connect to a service, retrying every 100ms for up to 10 seconds
result := node.exec_retry(
@@ -219,7 +219,7 @@ if node.dir_exists("/var/log") {
Transfer files between the local machine and the target node using `rsync` or `scp`.
```v
import freeflowuniverse.herolib.builder { SyncArgs }
import incubaid.herolib.builder { SyncArgs }
// Upload a local file to the remote node
node.upload(
@@ -286,7 +286,7 @@ node.hero_install()!
Updates the Herolib code on the node, with options for syncing from local, git reset, or git pull.
```v
import freeflowuniverse.herolib.builder { HeroUpdateArgs }
import incubaid.herolib.builder { HeroUpdateArgs }
// Sync local Herolib code to the remote node (full sync)
node.hero_update(sync_from_local: true, sync_full: true)!
@@ -300,7 +300,7 @@ node.hero_update(git_reset: true, branch: "dev")!
Uploads and executes a Vlang script (`.vsh` or `.v`) on the remote node.
```v
import freeflowuniverse.herolib.builder { VScriptArgs }
import incubaid.herolib.builder { VScriptArgs }
// Upload and execute a local V script on the remote node
node.vscript(path: "/local/path/to/my_script.vsh", sync_from_local: true)!
@@ -311,7 +311,7 @@ node.vscript(path: "/local/path/to/my_script.vsh", sync_from_local: true)!
The `portforward_to_local` function allows forwarding a remote port on an SSH host to a local port.
```v
import freeflowuniverse.herolib.builder { portforward_to_local, ForwardArgsToLocal }
import incubaid.herolib.builder { portforward_to_local, ForwardArgsToLocal }
// Forward remote port 8080 on 192.168.1.100 to local port 9000
portforward_to_local(

View File

@@ -13,12 +13,12 @@ prod_mode := fp.bool('prod', `p`, false, 'Build production version (optimized)')
help_requested := fp.bool('help', `h`, false, 'Show help message')
if help_requested {
println(fp.usage())
exit(0)
println(fp.usage())
exit(0)
}
additional_args := fp.finalize() or {
eprintln(err)
println(fp.usage())
exit(1)
}
eprintln(err)
println(fp.usage())
exit(1)
}

View File

@@ -0,0 +1,78 @@
{
"openrpc": "1.0.0-rc1",
"info": {
"title": "Simple RPC overview",
"version": "2.0.0"
},
"methods": [
{
"name": "get_versions",
"summary": "List API versions",
"params": [],
"result": {
"name": "get_version_result",
"schema": {
"type": "object"
}
},
"examples": [
{
"name": "v2",
"summary": "its a v2 example pairing!",
"description": "aight so this is how it works. You foo the bar then you baz the razmataz",
"params": [],
"result": {
"name": "versionsExample",
"value": {
"versions": [
{
"status": "CURRENT",
"updated": "2011-01-21T11:33:21Z",
"id": "v2.0",
"urls": [
{
"href": "http://127.0.0.1:8774/v2/",
"rel": "self"
}
]
},
{
"status": "EXPERIMENTAL",
"updated": "2013-07-23T11:33:21Z",
"id": "v3.0",
"urls": [
{
"href": "http://127.0.0.1:8774/v3/",
"rel": "self"
}
]
}
]
}
}
}
]
},
{
"name": "get_version_details",
"summary": "Show API version details",
"params": [],
"result": {
"name": "foo",
"schema": {
"type": "string"
}
},
"examples": [
{
"name": "stringifiedVersionsExample",
"params": [],
"result": {
"name": "bliggityblaow",
"value": "{\n \"versions\": [\n {\n \"status\": \"CURRENT\",\n \"updated\": \"2011-01-21T11:33:21Z\",\n \"id\": \"v2.0\",\n \"urls\": [\n {\n \"href\": \"http://127.0.0.1:8774/v2/\",\n \"rel\": \"self\"\n }\n ]\n },\n {\n \"status\": \"EXPERIMENTAL\",\n \"updated\": \"2013-07-23T11:33:21Z\",\n \"id\": \"v3.0\",\n \"urls\": [\n {\n \"href\": \"http://127.0.0.1:8774/v3/\",\n \"rel\": \"self\"\n }\n ]\n }\n ]\n}\n"
}
}
]
}
]
}

View File

@@ -1,420 +1,682 @@
# OSAL Core Module (freeflowuniverse.herolib.osal.core)
# OSAL Core Module (incubaid.herolib.osal.core)
This document describes the core functionalities of the Operating System Abstraction Layer (OSAL) module, designed for platform-independent system operations in V.
```v
//example how to get started
import freeflowuniverse.herolib.osal.core as osal
import incubaid.herolib.osal.core as osal
osal.exec(...)!
```
## 1. Process Management
### `osal.exec(cmd: Command) !Job`
Executes a shell command with extensive configuration.
* **Parameters**:
* `cmd` (`Command` struct):
* `cmd` (string): The command string.
* `timeout` (int, default: 3600): Max execution time in seconds.
* `retry` (int): Number of retries on failure.
* `work_folder` (string): Working directory.
* `environment` (map[string]string): Environment variables.
* `stdout` (bool, default: true): Show command output.
* `raise_error` (bool, default: true): Raise V error on failure.
* `ignore_error` (bool): Do not raise error, just report.
* `debug` (bool): Enable debug output.
* `shell` (bool): Execute in interactive shell.
* `async` (bool): Run command asynchronously.
* `runtime` (`RunTime` enum): Specify runtime (`.bash`, `.python`, etc.).
* **Returns**: `Job` struct (contains `status`, `output`, `error`, `exit_code`, `start`, `end`).
* **Error Handling**: Returns `JobError` with `error_type` (`.exec`, `.timeout`, `.args`).
* **Parameters**:
* `cmd` (`Command` struct):
* `cmd` (string): The command string.
* `timeout` (int, default: 3600): Max execution time in seconds.
* `retry` (int): Number of retries on failure.
* `work_folder` (string): Working directory.
* `environment` (map[string]string): Environment variables.
* `stdout` (bool, default: true): Show command output.
* `stdout_log` (bool, default: true): Log stdout to internal buffer.
* `raise_error` (bool, default: true): Raise V error on failure.
* `ignore_error` (bool): Do not raise error, just report.
* `debug` (bool): Enable debug output.
* `shell` (bool): Execute in interactive shell.
* `interactive` (bool, default: true): Run in interactive mode.
* `async` (bool): Run command asynchronously.
* `runtime` (`RunTime` enum): Specify runtime (`.bash`, `.python`, etc.).
* **Returns**: `Job` struct (contains `status`, `output`, `error`, `exit_code`, `start`, `end`, `process`, `runnr`).
* **Error Handling**: Returns `JobError` with `error_type` (`.exec`, `.timeout`, `.args`).
### `osal.execute_silent(cmd string) !string`
Executes a command silently.
* **Parameters**: `cmd` (string): The command string.
* **Returns**: `string` (command output).
* **Parameters**: `cmd` (string): The command string.
* **Returns**: `string` (command output).
### `osal.execute_debug(cmd string) !string`
Executes a command with debug output.
* **Parameters**: `cmd` (string): The command string.
* **Returns**: `string` (command output).
* **Parameters**: `cmd` (string): The command string.
* **Returns**: `string` (command output).
### `osal.execute_stdout(cmd string) !string`
Executes a command and prints output to stdout.
* **Parameters**: `cmd` (string): The command string.
* **Returns**: `string` (command output).
* **Parameters**: `cmd` (string): The command string.
* **Returns**: `string` (command output).
### `osal.execute_interactive(cmd string) !`
### `osal.execute_ok(cmd string) bool`
Executes a command and returns `true` if the command exits with a zero status, `false` otherwise.
* **Parameters**: `cmd` (string): The command string.
* **Returns**: `bool`.
Executes a command in an interactive shell.
* **Parameters**: `cmd` (string): The command string.
### `osal.exec_fast(cmd: CommandFast) !string`
Executes a command quickly, with options for profile sourcing and environment variables.
* **Parameters**:
* `cmd` (`CommandFast` struct):
* `cmd` (string): The command string.
* `ignore_error` (bool): Do not raise error on non-zero exit code.
* `work_folder` (string): Working directory.
* `environment` (map[string]string): Environment variables.
* `ignore_error_codes` ([]int): List of exit codes to ignore.
* `debug` (bool): Enable debug output.
* `includeprofile` (bool): Source the user's profile before execution.
* `notempty` (bool): Return an error if the output is empty.
* **Returns**: `string` (command output).
* **Parameters**: `cmd` (string): The command string.
### `osal.cmd_exists(cmd string) bool`
Checks if a command exists in the system's PATH.
* **Parameters**: `cmd` (string): The command name.
* **Returns**: `bool`.
* **Parameters**: `cmd` (string): The command name.
* **Returns**: `bool`.
### `osal.processmap_get() !ProcessMap`
Scans and returns a map of all running processes.
* **Returns**: `ProcessMap` struct (contains `processes` (`[]ProcessInfo`), `lastscan`, `state`, `pids`).
* **Returns**: `ProcessMap` struct (contains `processes` (`[]ProcessInfo`), `lastscan`, `state`, `pids`).
### `osal.processinfo_get(pid int) !ProcessInfo`
Retrieves detailed information for a specific process by PID.
* **Parameters**: `pid` (int): Process ID.
* **Returns**: `ProcessInfo` struct (contains `cpu_perc`, `mem_perc`, `cmd`, `pid`, `ppid`, `rss`).
* **Parameters**: `pid` (int): Process ID.
* **Returns**: `ProcessInfo` struct (contains `cpu_perc`, `mem_perc`, `cmd`, `pid`, `ppid`, `rss`).
### `osal.processinfo_get_byname(name string) ![]ProcessInfo`
Retrieves detailed information for processes matching a given name.
* **Parameters**: `name` (string): Process name (substring match).
* **Returns**: `[]ProcessInfo`.
* **Parameters**: `name` (string): Process name (substring match).
* **Returns**: `[]ProcessInfo`.
### `osal.process_exists(pid int) bool`
Checks if a process with a given PID exists.
* **Parameters**: `pid` (int): Process ID.
* **Returns**: `bool`.
* **Parameters**: `pid` (int): Process ID.
* **Returns**: `bool`.
### `osal.processinfo_with_children(pid int) !ProcessMap`
Returns a process and all its child processes.
* **Parameters**: `pid` (int): Parent Process ID.
* **Returns**: `ProcessMap`.
## 1.1. Done Context Management (`done.v`)
Functions for managing a "done" context or state using Redis.
* **`osal.done_set(key string, val string) !`**: Sets a key-value pair in the "done" context.
* **`osal.done_get(key string) ?string`**: Retrieves a value from the "done" context by key.
* **`osal.done_delete(key string) !`**: Deletes a key from the "done" context.
* **`osal.done_get_str(key string) string`**: Retrieves a string value from the "done" context by key (panics on error).
* **`osal.done_get_int(key string) int`**: Retrieves an integer value from the "done" context by key (panics on error).
* **`osal.done_exists(key string) bool`**: Checks if a key exists in the "done" context.
* **`osal.done_print() !`**: Prints all key-value pairs in the "done" context to debug output.
* **`osal.done_reset() !`**: Resets (deletes all keys from) the "done" context.
* **Parameters**: `pid` (int): Parent Process ID.
* **Returns**: `ProcessMap`.
### `osal.processinfo_children(pid int) !ProcessMap`
Returns all child processes for a given PID.
* **Parameters**: `pid` (int): Parent Process ID.
* **Returns**: `ProcessMap`.
* **Parameters**: `pid` (int): Parent Process ID.
* **Returns**: `ProcessMap`.
### `osal.process_kill_recursive(args: ProcessKillArgs) !`
Kills a process and all its children by name or PID.
* **Parameters**:
* `args` (`ProcessKillArgs` struct):
* `name` (string): Process name.
* `pid` (int): Process ID.
* **Parameters**:
* `args` (`ProcessKillArgs` struct):
* `name` (string): Process name.
* `pid` (int): Process ID.
### `osal.process_exists_byname(name string) !bool`
Checks if a process with a given name exists.
* **Parameters**: `name` (string): Process name (substring match).
* **Returns**: `bool`.
### `osal.whoami() !string`
Returns the current username.
* **Returns**: `string`.
* **Returns**: `string`.
## 2. Network Utilities
### `osal.ping(args: PingArgs) !PingResult`
### `osal.ping(args: PingArgs) ! bool`
Checks host reachability.
* **Parameters**:
* `args` (`PingArgs` struct):
* `address` (string, required): IP address or hostname.
* `count` (u8, default: 1): Number of pings.
* `timeout` (u16, default: 1): Timeout in seconds per ping.
* `retry` (u8): Number of retry attempts.
* **Returns**: `PingResult` enum (`.ok`, `.timeout`, `.unknownhost`).
### `osal.tcp_port_test(args: TcpPortTestArgs) bool`
Tests if a TCP port is open on a given address.
* **Parameters**:
* `args` (`TcpPortTestArgs` struct):
* `address` (string, required): IP address or hostname.
* `port` (int, default: 22): TCP port number.
* `timeout` (u16, default: 2000): Total timeout in milliseconds.
* **Returns**: `bool`.
* **Parameters**:
### `osal.ipaddr_pub_get() !string`
Retrieves the public IP address.
* **Returns**: `string`.
### `osal.ipaddr_pub_get_check() !string`
Retrieves the public IP address and verifies it is bound to a local interface.
* **Returns**: `string`.
### `osal.is_ip_on_local_interface(ip string) !bool`
Checks if a given IP address is bound to a local network interface.
* **Parameters**: `ip` (string): IP address to check.
* **Returns**: `bool`.
* **Parameters**: `ip` (string): IP address to check.
* **Returns**: `bool`.
* `args` (`PingArgs` struct):
* `address` (string, required): IP address or hostname.
* `count` (u8, default: 1): Number of pings.
* `timeout` (u16, default: 1): Timeout in seconds per ping.
* `retry` (u8): Number of retry attempts.
* **Returns**: `PingResult` enum (`.ok`, `.timeout`, `.unknownhost`).
### `osal.tcp_port_test(args: TcpPortTestArgs) bool`
Tests if a TCP port is open on a given address.
* **Parameters**:
* `args` (`TcpPortTestArgs` struct):
* `address` (string, required): IP address or hostname.
* `port` (int, default: 22): TCP port number.
* `timeout` (u16, default: 2000): Total timeout in milliseconds.
* **Returns**: `bool`.
### `osal.ipaddr_pub_get() !string`
Retrieves the public IP address.
* **Returns**: `string`.
### `osal.is_ip_on_local_interface(ip string) !bool`
Checks if a given IP address is bound to a local network interface.
* **Parameters**: `ip` (string): IP address to check.
* **Returns**: `bool`.
## 3. File System Operations
### `osal.file_write(path string, text string) !`
Writes text content to a file.
* **Parameters**:
* `path` (string): File path.
* `text` (string): Content to write.
* **Parameters**:
* `path` (string): File path.
* `text` (string): Content to write.
### `osal.file_read(path string) !string`
Reads content from a file.
* **Parameters**: `path` (string): File path.
* **Returns**: `string` (file content).
* **Parameters**: `path` (string): File path.
* **Returns**: `string` (file content).
### `osal.dir_ensure(path string) !`
Ensures a directory exists, creating it if necessary.
* **Parameters**: `path` (string): Directory path.
* **Parameters**: `path` (string): Directory path.
### `osal.dir_delete(path string) !`
Deletes a directory if it exists.
* **Parameters**: `path` (string): Directory path.
* **Parameters**: `path` (string): Directory path.
### `osal.dir_reset(path string) !`
Deletes and then recreates a directory.
* **Parameters**: `path` (string): Directory path.
* **Parameters**: `path` (string): Directory path.
### `osal.rm(todelete string) !`
Removes files or directories.
* **Parameters**: `todelete` (string): Comma or newline separated list of paths (supports `~` for home directory).
* **Parameters**: `todelete` (string): Comma or newline separated list of paths (supports `~` for home directory).
### `osal.env_get_all() map[string]string`
Returns all existing environment variables as a map.
* **Returns**: `map[string]string`.
## 4. Environment Variables
## 4.1. Package Management (`package.v`)
Functions for managing system packages.
* **`osal.package_refresh() !`**: Updates the package list for the detected platform.
* **`osal.package_install(name_ string) !`**: Installs one or more packages.
* **`osal.package_remove(name_ string) !`**: Removes one or more packages.
### `osal.env_set(args: EnvSet)`
Sets an environment variable.
* **Parameters**:
* `args` (`EnvSet` struct):
* `key` (string, required): Environment variable name.
* `value` (string, required): Value to set.
* `overwrite` (bool, default: true): Overwrite if exists.
* **Parameters**:
* `args` (`EnvSet` struct):
* `key` (string, required): Environment variable name.
* `value` (string, required): Value to set.
* `overwrite` (bool, default: true): Overwrite if exists.
### `osal.env_unset(key string)`
Unsets a specific environment variable.
* **Parameters**: `key` (string): Environment variable name.
* **Parameters**: `key` (string): Environment variable name.
### `osal.env_unset_all()`
Unsets all environment variables.
### `osal.env_set_all(args: EnvSetAll)`
Sets multiple environment variables.
* **Parameters**:
* `args` (`EnvSetAll` struct):
* `env` (map[string]string): Map of key-value pairs.
* `clear_before_set` (bool): Clear all existing variables before setting.
* `overwrite_if_exists` (bool, default: true): Overwrite existing variables.
* **Parameters**:
* `args` (`EnvSetAll` struct):
* `env` (map[string]string): Map of key-value pairs.
* `clear_before_set` (bool): Clear all existing variables before setting.
* `overwrite_if_exists` (bool, default: true): Overwrite existing variables.
### `osal.env_get(key string) !string`
Retrieves the value of a specific environment variable.
* **Parameters**: `key` (string): Environment variable name.
* **Returns**: `string` (variable value).
* **Parameters**: `key` (string): Environment variable name.
* **Returns**: `string` (variable value).
### `osal.env_exists(key string) !bool`
Checks if an environment variable exists.
* **Parameters**: `key` (string): Environment variable name.
* **Returns**: `bool`.
* **Parameters**: `key` (string): Environment variable name.
* **Returns**: `bool`.
### `osal.env_get_default(key string, def string) string`
Retrieves an environment variable or a default value if not found.
* **Parameters**:
* `key` (string): Environment variable name.
* `def` (string): Default value.
* **Returns**: `string`.
* **Parameters**:
* `key` (string): Environment variable name.
* `def` (string): Default value.
* **Returns**: `string`.
### `osal.load_env_file(file_path string) !`
Loads environment variables from a specified file.
* **Parameters**: `file_path` (string): Path to the environment file.
* **Parameters**: `file_path` (string): Path to the environment file.
## 5. Command & Profile Management
### `osal.cmd_add(args: CmdAddArgs) !`
Adds (copies or symlinks) a binary to system paths and updates user profiles.
* **Parameters**:
* `args` (`CmdAddArgs` struct):
* `cmdname` (string): Name of the command (optional, derived from source if empty).
* `source` (string, required): Path to the binary.
* `symlink` (bool): Create a symlink instead of copying.
* `reset` (bool, default: true): Delete existing command if found.
* **Parameters**:
* `args` (`CmdAddArgs` struct):
* `cmdname` (string): Name of the command (optional, derived from source if empty).
* `source` (string, required): Path to the binary.
* `symlink` (bool): Create a symlink instead of copying.
* `reset` (bool, default: true): Delete existing command if found.
### `osal.profile_path_add_hero() !string`
Ensures the `~/hero/bin` path is added to the user's profile.
* **Returns**: `string` (the `~/hero/bin` path).
* **Returns**: `string` (the `~/hero/bin` path).
### `osal.bin_path() !string`
Returns the preferred binary installation path (`~/hero/bin`).
* **Returns**: `string`.
* **Returns**: `string`.
### `osal.hero_path() !string`
Returns the `~/hero` directory path.
* **Returns**: `string`.
* **Returns**: `string`.
### `osal.usr_local_path() !string`
Returns `/usr/local` for Linux or `~/hero` for macOS.
* **Returns**: `string`.
* **Returns**: `string`.
### `osal.cmd_exists_profile(cmd string) bool`
Checks if a command exists in the system's PATH, considering the user's profile.
* **Parameters**: `cmd` (string): The command name.
* **Returns**: `bool`.
### `osal.profile_path_source() !string`
Returns a source statement for the preferred profile file (e.g., `. /home/user/.zprofile`).
* **Returns**: `string`.
* **Returns**: `string`.
### `osal.profile_path_source_and() !string`
Returns a source statement followed by `&&` for command chaining, or empty if profile doesn't exist.
* **Returns**: `string`.
* **Returns**: `string`.
### `osal.profile_path_add_remove(args: ProfilePathAddRemoveArgs) !`
Adds and/or removes paths from specified or preferred user profiles.
* **Parameters**:
* `args` (`ProfilePathAddRemoveArgs` struct):
* `paths_profile` (string): Comma/newline separated list of profile file paths (optional, uses preferred if empty).
* `paths2add` (string): Comma/newline separated list of paths to add.
* `paths2delete` (string): Comma/newline separated list of paths to delete.
* `allprofiles` (bool): Apply to all known profile files.
* **Parameters**:
* `args` (`ProfilePathAddRemoveArgs` struct):
* `paths_profile` (string): Comma/newline separated list of profile file paths (optional, uses preferred if empty).
* `paths2add` (string): Comma/newline separated list of paths to add.
* `paths2delete` (string): Comma/newline separated list of paths to delete.
* `allprofiles` (bool): Apply to all known profile files.
### `osal.cmd_path(cmd string) !string`
Returns the full path of an executable command using `which`.
* **Parameters**: `cmd` (string): Command name.
* **Returns**: `string` (full path).
* **Parameters**: `cmd` (string): Command name.
* **Returns**: `string` (full path).
### `osal.cmd_delete(cmd string) !`
Deletes commands from their found locations.
* **Parameters**: `cmd` (string): Command name.
* **Parameters**: `cmd` (string): Command name.
### `osal.profile_paths_all() ![]string`
Lists all possible profile file paths in the OS.
* **Returns**: `[]string`.
* **Returns**: `[]string`.
### `osal.profile_paths_preferred() ![]string`
## 5.1. SSH Key Management (`ssh_key.v`)
Functions and structs for managing SSH keys.
### `struct SSHKey`
Represents an SSH key pair.
* **Fields**: `name` (string), `directory` (string).
* **Methods**:
* `public_key_path() !pathlib.Path`: Returns the path to the public key.
* `private_key_path() !pathlib.Path`: Returns the path to the private key.
* `public_key() !string`: Returns the content of the public key.
* `private_key() !string`: Returns the content of the private key.
### `struct SSHConfig`
Configuration for SSH key operations.
* **Fields**: `directory` (string, default: `~/.ssh`).
### `osal.get_ssh_key(key_name string, config SSHConfig) ?SSHKey`
Retrieves a specific SSH key by name.
* **Parameters**: `key_name` (string), `config` (`SSHConfig` struct).
* **Returns**: `?SSHKey` (optional SSHKey struct).
### `osal.list_ssh_keys(config SSHConfig) ![]SSHKey`
Lists all SSH keys in the specified directory.
* **Parameters**: `config` (`SSHConfig` struct).
* **Returns**: `[]SSHKey`.
### `osal.new_ssh_key(key_name string, config SSHConfig) !SSHKey`
Creates a new SSH key pair.
* **Parameters**: `key_name` (string), `config` (`SSHConfig` struct).
* **Returns**: `SSHKey`.
Lists preferred profile file paths based on the operating system.
* **Returns**: `[]string`.
* **Returns**: `[]string`.
### `osal.profile_path() !string`
Returns the most preferred profile file path.
* **Returns**: `string`.
* **Returns**: `string`.
## 6. System Information & Utilities
### `osal.platform() !PlatformType`
Identifies the operating system.
* **Returns**: `PlatformType` enum (`.unknown`, `.osx`, `.ubuntu`, `.alpine`, `.arch`, `.suse`).
* **Returns**: `PlatformType` enum (`.unknown`, `.osx`, `.ubuntu`, `.alpine`, `.arch`, `.suse`).
### `osal.cputype() !CPUType`
Identifies the CPU architecture.
* **Returns**: `CPUType` enum (`.unknown`, `.intel`, `.arm`, `.intel32`, `.arm32`).
* **Returns**: `CPUType` enum (`.unknown`, `.intel`, `.arm`, `.intel32`, `.arm32`).
### `osal.is_linux() !bool`
Checks if the current OS is Linux.
* **Returns**: `bool`.
* **Returns**: `bool`.
### `osal.is_osx() !bool`
Checks if the current OS is macOS.
* **Returns**: `bool`.
* **Returns**: `bool`.
### `osal.is_ubuntu() !bool`
Checks if the current OS is Ubuntu.
* **Returns**: `bool`.
* **Returns**: `bool`.
### `osal.is_osx_arm() !bool`
Checks if the current OS is macOS ARM.
* **Returns**: `bool`.
* **Returns**: `bool`.
### `osal.is_linux_arm() !bool`
Checks if the current OS is Linux ARM.
* **Returns**: `bool`.
* **Returns**: `bool`.
### `osal.is_osx_intel() !bool`
Checks if the current OS is macOS Intel.
* **Returns**: `bool`.
* **Returns**: `bool`.
### `osal.is_linux_intel() !bool`
Checks if the current OS is Linux Intel.
* **Returns**: `bool`.
* **Returns**: `bool`.
### `osal.hostname() !string`
Returns the system hostname.
* **Returns**: `string`.
* **Returns**: `string`.
### `osal.initname() !string`
Returns the init system name (e.g., `systemd`, `bash`, `zinit`).
* **Returns**: `string`.
* **Returns**: `string`.
### `osal.sleep(duration int)`
Pauses execution for a specified duration.
* **Parameters**: `duration` (int): Sleep duration in seconds.
* **Parameters**: `duration` (int): Sleep duration in seconds.
### `osal.download(args: DownloadArgs) !pathlib.Path`
Downloads a file from a URL.
* **Parameters**:
* `args` (`DownloadArgs` struct):
* `url` (string, required): URL of the file.
* `name` (string): Optional, derived from filename if empty.
* `reset` (bool): Force download, remove existing.
* `hash` (string): Hash for verification.
* `dest` (string): Destination path.
* `timeout` (int, default: 180): Download timeout in seconds.
* `retry` (int, default: 3): Number of retries.
* `minsize_kb` (u32, default: 10): Minimum expected size in KB.
* `maxsize_kb` (u32): Maximum expected size in KB.
* `expand_dir` (string): Directory to expand archive into.
* `expand_file` (string): File to expand archive into.
* **Returns**: `pathlib.Path` (path to the downloaded file/directory).
* **Parameters**:
* `args` (`DownloadArgs` struct):
* `url` (string, required): URL of the file.
* `name` (string): Optional, derived from filename if empty.
* `reset` (bool): Force download, remove existing.
* `hash` (string): Hash for verification.
* `dest` (string): Destination path.
* `timeout` (int, default: 180): Download timeout in seconds.
* `retry` (int, default: 3): Number of retries.
* `minsize_kb` (u32, default: 10): Minimum expected size in KB.
* `maxsize_kb` (u32): Maximum expected size in KB.
* `expand_dir` (string): Directory to expand archive into.
* `expand_file` (string): File to expand archive into.
* **Returns**: `pathlib.Path` (path to the downloaded file/directory).
### `osal.user_exists(username string) bool`
Checks if a user exists on the system.
* **Parameters**: `username` (string): Username to check.
* **Returns**: `bool`.
* **Parameters**: `username` (string): Username to check.
* **Returns**: `bool`.
### `osal.user_id_get(username string) !int`
Retrieves the user ID for a given username.
* **Parameters**: `username` (string): Username.
* **Returns**: `int` (User ID).
* **Parameters**: `username` (string): Username.
* **Returns**: `int` (User ID).
### `osal.user_add(args: UserArgs) !int`
Adds a new user to the system.
* **Parameters**:
* `args` (`UserArgs` struct):
* `name` (string, required): Username to add.
* **Returns**: `int` (User ID of the added user).
* **Parameters**:
* `args` (`UserArgs` struct):
* `name` (string, required): Username to add.
* **Returns**: `int` (User ID of the added user).
## Enums & Structs
### `enum PlatformType`
Represents the detected operating system.
* Values: `unknown`, `osx`, `ubuntu`, `alpine`, `arch`, `suse`.
* Values: `unknown`, `osx`, `ubuntu`, `alpine`, `arch`, `suse`.
### `enum CPUType`
Represents the detected CPU architecture.
* Values: `unknown`, `intel`, `arm`, `intel32`, `arm32`.
* Values: `unknown`, `intel`, `arm`, `intel32`, `arm32`.
### `enum RunTime`
Specifies the runtime environment for command execution.
* Values: `bash`, `python`, `heroscript`, `herocmd`, `v`.
* Values: `bash`, `python`, `heroscript`, `herocmd`, `v`.
### `enum JobStatus`
Status of an executed command job.
* Values: `init`, `running`, `error_exec`, `error_timeout`, `error_args`, `done`.
* Values: `init`, `running`, `error_exec`, `error_timeout`, `error_args`, `done`.
### `enum ErrorType`
Types of errors that can occur during job execution.
* Values: `exec`, `timeout`, `args`.
* Values: `exec`, `timeout`, `args`.
### `enum PingResult`
Result of a ping operation.
* Values: `ok`, `timeout`, `unknownhost`.
* Values: `ok`, `timeout`, `unknownhost`.
### `struct Command`
Configuration for `osal.exec` function. (See `osal.exec` parameters for fields).
### `struct Job`
Result object returned by `osal.exec`. (See `osal.exec` returns for fields).
### `struct JobError`
Error details for failed jobs.
### `struct PingArgs`
Arguments for `osal.ping` function. (See `osal.ping` parameters for fields).
### `struct TcpPortTestArgs`
Arguments for `osal.tcp_port_test` function. (See `osal.tcp_port_test` parameters for fields).
### `struct EnvSet`
Arguments for `osal.env_set` function. (See `osal.env_set` parameters for fields).
### `struct EnvSetAll`
Arguments for `osal.env_set_all` function. (See `osal.env_set_all` parameters for fields).
### `struct CmdAddArgs`
Arguments for `osal.cmd_add` function. (See `osal.cmd_add` parameters for fields).
### `struct ProfilePathAddRemoveArgs`
Arguments for `osal.profile_path_add_remove` function. (See `osal.profile_path_add_remove` parameters for fields).
### `struct ProcessMap`
Contains a list of `ProcessInfo` objects.
### `struct ProcessInfo`
Detailed information about a single process. (See `osal.processinfo_get` returns for fields).
### `struct ProcessKillArgs`
Arguments for `osal.process_kill_recursive` function. (See `osal.process_kill_recursive` parameters for fields).
### `struct DownloadArgs`
Arguments for `osal.download` function. (See `osal.download` parameters for fields).
### `struct UserArgs`
Arguments for `osal.user_add` function. (See `osal.user_add` parameters for fields).

View File

@@ -3,6 +3,7 @@
The `OurTime` module in V provides flexible time handling, supporting relative and absolute time formats, Unix timestamps, and formatting utilities.
## Key Features
- Create time objects from strings or current time
- Relative time expressions (e.g., `+1h`, `-2d`)
- Absolute time formats (e.g., `YYYY-MM-DD HH:mm:ss`)
@@ -12,7 +13,7 @@ The `OurTime` module in V provides flexible time handling, supporting relative a
## Basic Usage
```v
import freeflowuniverse.herolib.data.ourtime
import incubaid.herolib.data.ourtime
// Current time
mut t := ourtime.now()

View File

@@ -1,6 +1,6 @@
# Herolib Spreadsheet Module for AI Prompt Engineering
This document provides an overview and usage instructions for the `freeflowuniverse.herolib.biz.spreadsheet` module, which offers a powerful software representation of a spreadsheet. This module is designed for business modeling, data analysis, and can be leveraged in AI prompt engineering scenarios where structured data manipulation and visualization are required.
This document provides an overview and usage instructions for the `incubaid.herolib.biz.spreadsheet` module, which offers a powerful software representation of a spreadsheet. This module is designed for business modeling, data analysis, and can be leveraged in AI prompt engineering scenarios where structured data manipulation and visualization are required.
## 1. Core Concepts
@@ -10,16 +10,17 @@ The spreadsheet module revolves around three main entities: `Sheet`, `Row`, and
The `Sheet` is the primary container, representing the entire spreadsheet.
* **Properties:**
* `name` (string): A unique identifier for the sheet.
* `rows` (map[string]&Row): A collection of `Row` objects, indexed by their names.
* `nrcol` (int): The number of columns in the sheet (e.g., 60 for 5 years of monthly data).
* `params` (SheetParams): Configuration parameters, e.g., `visualize_cur` (boolean to display currency symbols).
* `currency` (currency.Currency): The default currency for the sheet (e.g., USD), used for automatic conversions.
* **Properties:**
* `name` (string): A unique identifier for the sheet.
* `rows` (map[string]&Row): A collection of `Row` objects, indexed by their names.
* `nrcol` (int): The number of columns in the sheet (e.g., 60 for 5 years of monthly data).
* `params` (SheetParams): Configuration parameters, e.g., `visualize_cur` (boolean to display currency symbols).
* `currency` (currency.Currency): The default currency for the sheet (e.g., USD), used for automatic conversions.
* **Creation:**
* **Creation:**
```v
import freeflowuniverse.herolib.biz.spreadsheet
import incubaid.herolib.biz.spreadsheet
// Create a new sheet named 'my_financial_sheet' with 60 columns (e.g., 60 months)
mut my_sheet := spreadsheet.sheet_new(
@@ -33,28 +34,29 @@ The `Sheet` is the primary container, representing the entire spreadsheet.
mut existing_sheet := spreadsheet.sheet_get('my_financial_sheet')!
```
* **Key Operations:**
* `sheet.row_get(name string) !&Row`: Retrieves a row by its name.
* `sheet.cell_get(row string, col int) !&Cell`: Retrieves a cell by row name and column index.
* `sheet.row_delete(name string)` / `sheet.delete(name string)`: Deletes a row.
* `sheet.cells_width(colnr int) !int`: Finds the maximum string length of cells in a given column.
* `sheet.rows_names_width_max() int`: Returns the maximum width of row names/aliases.
* `sheet.rows_description_width_max() int`: Returns the maximum width of row descriptions.
* `sheet.header() ![]string`: Generates column headers (e.g., "M1", "Q1", "Y1") based on `nrcol`.
* **Key Operations:**
* `sheet.row_get(name string) !&Row`: Retrieves a row by its name.
* `sheet.cell_get(row string, col int) !&Cell`: Retrieves a cell by row name and column index.
* `sheet.row_delete(name string)` / `sheet.delete(name string)`: Deletes a row.
* `sheet.cells_width(colnr int) !int`: Finds the maximum string length of cells in a given column.
* `sheet.rows_names_width_max() int`: Returns the maximum width of row names/aliases.
* `sheet.rows_description_width_max() int`: Returns the maximum width of row descriptions.
* `sheet.header() ![]string`: Generates column headers (e.g., "M1", "Q1", "Y1") based on `nrcol`.
### 1.2. Row
A `Row` represents a single horizontal line of data within a `Sheet`.
* **Properties:**
* `name` (string): Unique identifier for the row.
* `alias` (string, optional): Alternative name.
* `description` (string): Textual description.
* `tags` (string): Space-separated tags for categorization (e.g., "department:hr location:belgium").
* `cells` ([]Cell): List of `Cell` objects.
* `aggregatetype` (RowAggregateType): Defines default aggregation for this row (`.sum`, `.avg`, `.max`, `.min`).
* **Properties:**
* `name` (string): Unique identifier for the row.
* `alias` (string, optional): Alternative name.
* `description` (string): Textual description.
* `tags` (string): Space-separated tags for categorization (e.g., "department:hr location:belgium").
* `cells` ([]Cell): List of `Cell` objects.
* `aggregatetype` (RowAggregateType): Defines default aggregation for this row (`.sum`, `.avg`, `.max`, `.min`).
* **Creation (within a Sheet):**
* **Creation (within a Sheet):**
```v
// Assuming 'my_sheet' is an existing Sheet object
mut salaries_row := my_sheet.row_new(
@@ -65,21 +67,21 @@ A `Row` represents a single horizontal line of data within a `Sheet`.
)!
```
* **Key Operations:**
* `row.values_get() []f64`: Returns all cell values in the row as a list of floats.
* **Key Operations:**
* `row.values_get() []f64`: Returns all cell values in the row as a list of floats.
### 1.3. Cell
A `Cell` is the fundamental unit of data, storing a numeric value.
* **Properties:**
* `val` (f64): The numeric value.
* `empty` (bool): `true` if the cell is empty.
* **Properties:**
* `val` (f64): The numeric value.
* `empty` (bool): `true` if the cell is empty.
* **Key Operations:**
* `cell.set(v string) !`: Sets the cell's value. Handles currency strings (e.g., "100 USD") by converting to the sheet's currency.
* `cell.add(v f64)`: Adds a numeric value to the existing cell value.
* `cell.repr() string`: Returns a formatted string representation of the value (e.g., "100.00", or "-" if empty).
* **Key Operations:**
* `cell.set(v string) !`: Sets the cell's value. Handles currency strings (e.g., "100 USD") by converting to the sheet's currency.
* `cell.add(v f64)`: Adds a numeric value to the existing cell value.
* `cell.repr() string`: Returns a formatted string representation of the value (e.g., "100.00", or "-" if empty).
## 2. Data Aggregation and Transformation
@@ -144,10 +146,10 @@ csv_string := my_sheet.export_csv(path: '')!
println(csv_string)
```
* **`ExportCSVArgs` Parameters:**
* `path` (string, optional): File path. Empty string returns content as string. `~` is expanded to home directory.
* `include_empty` (bool, optional, default: `false`): If `true`, empty cells are included.
* `separator` (string, optional, default: `'|'`): Delimiter character.
* **`ExportCSVArgs` Parameters:**
* `path` (string, optional): File path. Empty string returns content as string. `~` is expanded to home directory.
* `include_empty` (bool, optional, default: `false`): If `true`, empty cells are included.
* `separator` (string, optional, default: `'|'`): Delimiter character.
## 4. Charting Capabilities
@@ -157,25 +159,26 @@ Integrates with ECharts for data visualization. Charting functions return an `ec
Used across line, bar, and pie charts to specify data and presentation.
* `rowname` (string, optional): Single row name or comma-separated list.
* `namefilter` ([]string, optional): List of exact row names to include.
* `includefilter` ([]string, optional): List of tags to include.
* `excludefilter` ([]string, optional): List of tags to exclude.
* `period_type` (PeriodType, optional): X-axis period (`.month`, `.quarter`, `.year`).
* `aggregate` (bool, optional, default: `true`): Aggregate multiple matching rows.
* `aggregatetype` (RowAggregateType, optional, default: `.sum`): Aggregation type.
* `unit` (UnitType, optional): Data unit.
* `title`, `title_sub` (string, optional): Chart titles.
* `size` (string, optional): For pie charts, defines radius (e.g., "70%").
* `rowname_show` (bool, optional, default: `true`): Show row name in legend.
* `descr_show` (bool, optional, default: `false`): Show row description (overrides `rowname_show`).
* `description` (string, optional): General chart description.
* `rowname` (string, optional): Single row name or comma-separated list.
* `namefilter` ([]string, optional): List of exact row names to include.
* `includefilter` ([]string, optional): List of tags to include.
* `excludefilter` ([]string, optional): List of tags to exclude.
* `period_type` (PeriodType, optional): X-axis period (`.month`, `.quarter`, `.year`).
* `aggregate` (bool, optional, default: `true`): Aggregate multiple matching rows.
* `aggregatetype` (RowAggregateType, optional, default: `.sum`): Aggregation type.
* `unit` (UnitType, optional): Data unit.
* `title`, `title_sub` (string, optional): Chart titles.
* `size` (string, optional): For pie charts, defines radius (e.g., "70%").
* `rowname_show` (bool, optional, default: `true`): Show row name in legend.
* `descr_show` (bool, optional, default: `false`): Show row description (overrides `rowname_show`).
* `description` (string, optional): General chart description.
### 4.2. Chart Types
* **Line Chart (`line_chart`)**: Visualizes trends over time.
* **Line Chart (`line_chart`)**: Visualizes trends over time.
```v
import freeflowuniverse.herolib.web.echarts // Required for EChartsOption type
import incubaid.herolib.web.echarts // Required for EChartsOption type
line_chart_option := my_sheet.line_chart(
rowname: 'revenue_row,expenses_row',
@@ -184,7 +187,8 @@ Used across line, bar, and pie charts to specify data and presentation.
)!
```
* **Bar Chart (`bar_chart`)**: Compares discrete categories or values.
* **Bar Chart (`bar_chart`)**: Compares discrete categories or values.
```v
bar_chart_option := my_sheet.bar_chart(
rowname: 'profit_row',
@@ -193,7 +197,8 @@ Used across line, bar, and pie charts to specify data and presentation.
)!
```
* **Pie Chart (`pie_chart`)**: Shows proportions of categories.
* **Pie Chart (`pie_chart`)**: Shows proportions of categories.
```v
pie_chart_option := my_sheet.pie_chart(
rowname: 'budget_allocation_row',
@@ -203,4 +208,4 @@ Used across line, bar, and pie charts to specify data and presentation.
)!
```
This documentation should provide sufficient information for an AI to understand and utilize the `lib/biz/spreadsheet` module effectively for various data manipulation and visualization tasks.
This documentation should provide sufficient information for an AI to understand and utilize the `lib/biz/spreadsheet` module effectively for various data manipulation and visualization tasks.

View File

@@ -7,8 +7,8 @@ Chalk offers functions:- `console.color_fg(text string, color string)` - To chan
Example:
```vlang
import freeflowuniverse.herolib.ui.console
```v
import incubaid.herolib.ui.console
# basic usage
println('I am really ' + console.color_fg('happy', 'green'))

View File

@@ -0,0 +1,72 @@
# BASIC INSTRUCTIONS
IMPORTANT: USE THIS PAGE AS THE ABSOLUTE AUTHORITY ON ALL INSTRUCTIONS
## instructions for code generation
> when I generate code, the following instructions can never be overruled they are the basics
- do not try to fix files which end with _.v because these are generated files
## instruction for vlang scripts
when I generate vlang scripts I will always use .vsh extension and use following as first line:
```
#!/usr/bin/env -S v -n -w -cg -gc none -cc tcc -d use_openssl -enable-globals run
```
- a .vsh is a v shell script and can be executed as is, no need to use v ...
- in .vsh file there is no need for a main() function
- these scripts can be used for examples or instruction scripts e.g. an installs script
## executing vlang scripts
As AI agent I should also execute .v or .vsh scripts with vrun
```bash
vrun ~/code/github/incubaid/herolib/examples/biztools/bizmodel.vsh
```
## executing test scripts
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/incubaid/herolib/lib/osal/package_test.v
```
- use ~ so it works over all machines
- don't use 'v test', we have vtest as alternative
## module imports
- in v all files in a folder are part of the same module, no need to import then, this is important difference in v
## usage of @[params]
- this is the best way how to pass optional parameters to functions in V
```
@[params]
pub struct MyArgs {
pub mut:
name string
passphrase string
}
pub fn my_function(args MyArgs) {
// Use args.name and args.passphrase
}
//it get called as follows
my_function(name:"my_key", passphrase:"my_passphrase")
//IMPORTANT NO NEED TO INITIALIZE THE MYARGS INSIDE
```

View File

@@ -6,39 +6,39 @@ the following is a good pragmatic way to remember clients, installers as a globa
module docsite
import freeflowuniverse.herolib.core.texttools
import incubaid.herolib.core.texttools
__global (
siteconfigs map[string]&SiteConfig
siteconfigs map[string]&SiteConfig
)
@[params]
pub struct FactoryArgs {
pub mut:
name string = "default"
name string = "default"
}
pub fn new(args FactoryArgs) !&SiteConfig {
name := texttools.name_fix(args.name)
siteconfigs[name] = &SiteConfig{
name: name
}
return get(name:name)!
name := texttools.name_fix(args.name)
siteconfigs[name] = &SiteConfig{
name: name
}
return get(name:name)!
}
pub fn get(args FactoryArgs) !&SiteConfig {
name := texttools.name_fix(args.name)
mut sc := siteconfigs[name] or {
return error('siteconfig with name "${name}" does not exist')
}
return sc
name := texttools.name_fix(args.name)
mut sc := siteconfigs[name] or {
return error('siteconfig with name "${name}" does not exist')
}
return sc
}
pub fn default() !&SiteConfig {
if siteconfigs.len == 0 {
return new(name:'default')!
}
return get()!
if siteconfigs.len == 0 {
return new(name:'default')!
}
return get()!
}
```
```

View File

@@ -6,49 +6,49 @@ HeroScript is a concise scripting language with the following structure:
```heroscript
!!actor.action_name
param1: 'value1'
param2: 'value with spaces'
multiline_description: '
This is a multiline description.
It can span multiple lines.
'
arg1 arg2 // Arguments without keys
param1: 'value1'
param2: 'value with spaces'
multiline_description: '
This is a multiline description.
It can span multiple lines.
'
arg1 arg2 // Arguments without keys
```
Key characteristics:
- **Actions**: Start with `!!`, followed by `actor.action_name` (e.g., `!!mailclient.configure`).
- **Parameters**: Defined as `key:value`. Values can be quoted for spaces.
- **Multiline Support**: Parameters like `description` can span multiple lines.
- **Arguments**: Values without keys (e.g., `arg1`).
- **Actions**: Start with `!!`, followed by `actor.action_name` (e.g., `!!mailclient.configure`).
- **Parameters**: Defined as `key:value`. Values can be quoted for spaces.
- **Multiline Support**: Parameters like `description` can span multiple lines.
- **Arguments**: Values without keys (e.g., `arg1`).
## Processing HeroScript in Vlang
HeroScript can be parsed into a `playbook.PlayBook` object, allowing structured access to actions and their parameters, this is used in most of the herolib modules, it allows configuration or actions in a structured way.
```v
import freeflowuniverse.herolib.core.playbook { PlayBook }
import freeflowuniverse.herolib.ui.console
import incubaid.herolib.core.playbook { PlayBook }
import incubaid.herolib.ui.console
pub fn play(mut plbook PlayBook) ! {
if plbook.exists_once(filter: 'docusaurus.define') {
mut action := plbook.get(filter: 'docusaurus.define')!
mut p := action.params
//example how we get parameters from the action see core_params.md for more details
ds = new(
path: p.get_default('path_publish', '')!
production: p.get_default_false('production')
)!
}
if plbook.exists_once(filter: 'docusaurus.define') {
mut action := plbook.get(filter: 'docusaurus.define')!
mut p := action.params
//example how we get parameters from the action see aiprompts/herolib_core/core_params.md for more details
path_build := p.get_default('path_build', '')!
path_publish := p.get_default('path_publish', '')!
reset := p.get_default_false('reset')
use_doctree := p.get_default_false('use_doctree')
}
// Process 'docusaurus.add' actions to configure individual Docusaurus sites
actions := plbook.find(filter: 'docusaurus.add')!
for action in actions {
mut p := action.params
//do more processing here
}
// Process 'docusaurus.add' actions to configure individual Docusaurus sites
actions := plbook.find(filter: 'docusaurus.add')!
for action in actions {
mut p := action.params
//do more processing here
}
}
```
For detailed information on parameter retrieval methods (e.g., `p.get()`, `p.get_int()`, `p.get_default_true()`), refer to `aiprompts/ai_core/core_params.md`.
For detailed information on parameter retrieval methods (e.g., `p.get()`, `p.get_int()`, `p.get_default_true()`), refer to `aiprompts/herolib_core/core_params.md`.

View File

@@ -5,8 +5,8 @@
HeroScript can be parsed into a `playbook.PlayBook` object, allowing structured access to actions and their parameters.
```v
import freeflowuniverse.herolib.core.playbook
import freeflowuniverse.herolib.core.playcmds
import incubaid.herolib.core.playbook
import incubaid.herolib.core.playcmds
// path string
// text string
@@ -21,5 +21,3 @@ mut plbook := playbook.new(path: "....")!
playcmds.run(mut plbook)!
```

View File

@@ -3,6 +3,7 @@
The `HTTPConnection` module provides a robust HTTP client for Vlang, supporting JSON, custom headers, retries, and caching.
## Key Features
- Type-safe JSON methods
- Custom headers
- Retry mechanism
@@ -12,7 +13,7 @@ The `HTTPConnection` module provides a robust HTTP client for Vlang, supporting
## Basic Usage
```v
import freeflowuniverse.herolib.core.httpconnection
import incubaid.herolib.core.httpconnection
// Create a new HTTP connection
mut conn := httpconnection.new(
@@ -30,17 +31,17 @@ To integrate `HTTPConnection` into a management class (e.g., `HetznerManager`),
```v
// Example: HetznerManager
pub fn (mut h HetznerManager) connection() !&httpconnection.HTTPConnection {
mut c := h.conn or {
mut c2 := httpconnection.new(
name: 'hetzner_${h.name}'
url: h.baseurl
cache: true
retry: 3
)!
c2.basic_auth(h.user, h.password)
c2
}
return c
mut c := h.conn or {
mut c2 := httpconnection.new(
name: 'hetzner_${h.name}'
url: h.baseurl
cache: true
retry: 3
)!
c2.basic_auth(h.user, h.password)
c2
}
return c
}
```

View File

@@ -1,63 +1,84 @@
# OSAL Core Module - Key Capabilities (freeflowuniverse.herolib.osal.core)
# OSAL Core Module - Key Capabilities (incubaid.herolib.osal.core)
> **Note:** Platform detection functions (`platform()` and `cputype()`) have moved to `incubaid.herolib.core`.
> Use `import incubaid.herolib.core` and call `core.platform()!` and `core.cputype()!` instead.
```v
//example how to get started
import freeflowuniverse.herolib.osal.core as osal
osal.exec(cmd:"ls /")!
import incubaid.herolib.osal.core as osal
job := osal.exec(cmd: 'ls /')!
```
this document has info about the most core functions, more detailed info can be found in `aiprompts/herolib_advanced/osal.md` if needed.
This document describes the core functionalities of the Operating System Abstraction Layer (OSAL) module, designed for platform-independent system operations in V.
## Key Functions
## 1. Process Execution
### 1. Process Execution
* **`osal.exec(cmd: Command) !Job`**: Execute a shell command.
* **Key Parameters**: `cmd` (string), `timeout` (int), `retry` (int), `work_folder` (string), `environment` (map[string]string), `stdout` (bool), `raise_error` (bool).
* **Returns**: `Job` (status, output, error, exit code).
* **`osal.execute_silent(cmd string) !string`**: Execute silently, return output.
* **`osal.execute_debug(cmd string) !string`**: Execute with debug output, return output.
* **`osal.execute_stdout(cmd string) !string`**: Execute and print output to stdout, return output.
* **`osal.execute_interactive(cmd string) !`**: Execute in an interactive shell.
* **`osal.cmd_exists(cmd string) bool`**: Check if a command exists.
* **`osal.exec(cmd: Command) !Job`**: Execute a shell command.
* **Key Parameters**: `cmd` (string), `timeout` (int), `retry` (int), `work_folder` (string), `environment` (map[string]string), `stdout` (bool), `raise_error` (bool).
* **Returns**: `Job` (status, output, error, exit code).
* **`osal.execute_silent(cmd string) !string`**: Execute silently, return output.
* **`osal.cmd_exists(cmd string) bool`**: Check if a command exists.
* **`osal.process_kill_recursive(args: ProcessKillArgs) !`**: Kill a process and its children.
## 2. Network Utilities
### 2. Network Utilities
* **`osal.ping(args: PingArgs) !bool`**: Check host reachability.
- address string = "8.8.8.8"
- nr_ping u16 = 3 // amount of ping requests we will do
- nr_ok u16 = 3 //how many of them need to be ok
- retry u8 //how many times fo we retry above sequence, basically we ping ourselves with -c 1
**`osal.ipaddr_pub_get() !string`**: Get public IP address.
* **`osal.ping(args: PingArgs) !PingResult`**: Check host reachability.
* **Key Parameters**: `address` (string).
* **Returns**: `PingResult` (`.ok`, `.timeout`, `.unknownhost`).
* **`osal.tcp_port_test(args: TcpPortTestArgs) bool`**: Test if a TCP port is open.
* **Key Parameters**: `address` (string), `port` (int).
* **`osal.ipaddr_pub_get() !string`**: Get public IP address.
## 3. File System Operations
### 3. File System Operations
* **`osal.file_write(path string, text string) !`**: Write text to a file.
* **`osal.file_read(path string) !string`**: Read content from a file.
* **`osal.dir_ensure(path string) !`**: Ensure a directory exists.
* **`osal.rm(todelete string) !`**: Remove files/directories.
* **`osal.file_write(path string, text string) !`**: Write text to a file.
* **`osal.file_read(path string) !string`**: Read content from a file.
* **`osal.dir_ensure(path string) !`**: Ensure a directory exists.
* **`osal.rm(todelete string) !`**: Remove files/directories.
## 4. Environment Variables
### 4. Environment Variables
* **`osal.env_set(args: EnvSet)`**: Set an environment variable.
* **Key Parameters**: `key` (string), `value` (string).
* **`osal.env_unset(key string)`**: Unset a specific environment variable.
* **`osal.env_unset_all()`**: Unset all environment variables.
* **`osal.env_set_all(args: EnvSetAll)`**: Set multiple environment variables.
* **Key Parameters**: `env` (map[string]string), `clear_before_set` (bool), `overwrite_if_exists` (bool).
* **`osal.env_get(key string) !string`**: Get an environment variable's value.
* **`osal.env_exists(key string) !bool`**: Check if an environment variable exists.
* **`osal.env_get_default(key string, def string) string`**: Get an environment variable or a default value.
* **`osal.load_env_file(file_path string) !`**: Load variables from a file.
* **`osal.env_set(args: EnvSet)`**: Set an environment variable.
* **Key Parameters**: `key` (string), `value` (string).
* **`osal.env_get(key string) !string`**: Get an environment variable's value.
* **`osal.load_env_file(file_path string) !`**: Load variables from a file.
## 5. Command & Profile Management
### 5. Command & Profile Management
* **`osal.cmd_add(args: CmdAddArgs) !`**: Add a binary to system paths and update profiles.
* **Key Parameters**: `source` (string, required), `cmdname` (string).
* **`osal.profile_path_add_remove(args: ProfilePathAddRemoveArgs) !`**: Add/remove paths from profiles.
* **Key Parameters**: `paths2add` (string), `paths2delete` (string).
* **`osal.cmd_add(args: CmdAddArgs) !`**: Add a binary to system paths and update profiles.
* **Key Parameters**: `source` (string, required), `cmdname` (string).
* **`osal.profile_path_add_remove(args: ProfilePathAddRemoveArgs) !`**: Add/remove paths from profiles.
* **Key Parameters**: `paths2add` (string), `paths2delete` (string).
### 6. System Information
* **`osal.platform() !PlatformType`**: Identify the operating system.
* **`osal.cputype() !CPUType`**: Identify the CPU architecture.
* **`osal.hostname() !string`**: Get system hostname.
---
## 6. System Information & Utilities
* **`osal.processmap_get() !ProcessMap`**: Get a map of all running processes.
* **`osal.processinfo_get(pid int) !ProcessInfo`**: Get detailed information for a specific process.
* **`osal.processinfo_get_byname(name string) ![]ProcessInfo`**: Get info for processes matching a name.
* **`osal.process_exists(pid int) bool`**: Check if a process exists by PID.
* **`osal.processinfo_with_children(pid int) !ProcessMap`**: Get a process and its children.
* **`osal.processinfo_children(pid int) !ProcessMap`**: Get children of a process.
* **`osal.process_kill_recursive(args: ProcessKillArgs) !`**: Kill a process and its children.
* **Key Parameters**: `name` (string), `pid` (int).
* **`osal.whoami() !string`**: Return the current username.
* ~~**`osal.platform() !PlatformType`**: Identify the operating system.~~ → **Moved to `incubaid.herolib.core`**
* ~~**`osal.cputype() !CPUType`**: Identify the CPU architecture.~~ → **Moved to `incubaid.herolib.core`**
* **`osal.hostname() !string`**: Get system hostname.
* **`osal.sleep(duration int)`**: Pause execution for a specified duration.
* **`osal.download(args: DownloadArgs) !pathlib.Path`**: Download a file from a URL.
* `pathlib.Path` is from `incubaid.herolib.core.pathlib`
* **Key Parameters**: `url` (string), `dest` (string), `timeout` (int), `retry` (int).
* **`osal.user_exists(username string) bool`**: Check if a user exists.
* **`osal.user_id_get(username string) !int`**: Get user ID.
* **`osal.user_add(args: UserArgs) !int`**: Add a user.
* **Key Parameters**: `name` (string).

View File

@@ -3,6 +3,7 @@
The `OurTime` module in V provides flexible time handling, supporting relative and absolute time formats, Unix timestamps, and formatting utilities.
## Key Features
- Create time objects from strings or current time
- Relative time expressions (e.g., `+1h`, `-2d`)
- Absolute time formats (e.g., `YYYY-MM-DD HH:mm:ss`)
@@ -12,7 +13,7 @@ The `OurTime` module in V provides flexible time handling, supporting relative a
## Basic Usage
```v
import freeflowuniverse.herolib.data.ourtime
import incubaid.herolib.data.ourtime
// Current time
mut t := ourtime.now()

View File

@@ -5,7 +5,7 @@ This document details the `paramsparser` module, essential for handling paramete
## Obtaining a `paramsparser` Instance
```v
import freeflowuniverse.herolib.data.paramsparser
import incubaid.herolib.data.paramsparser
// Create new params from a string
params := paramsparser.new("color:red size:'large' priority:1 enable:true")!
@@ -19,13 +19,14 @@ params.set("color", "red")
The parser supports various input formats:
1. **Key-value pairs**: `key:value`
2. **Quoted values**: `key:'value with spaces'` (single or double quotes)
3. **Arguments without keys**: `arg1 arg2` (accessed by index)
4. **Comments**: `// this is a comment` (ignored during parsing)
1. **Key-value pairs**: `key:value`
2. **Quoted values**: `key:'value with spaces'` (single or double quotes)
3. **Arguments without keys**: `arg1 arg2` (accessed by index)
4. **Comments**: `// this is a comment` (ignored during parsing)
Example:
```vlang
```v
text := "name:'John Doe' age:30 active:true // user details"
params := paramsparser.new(text)!
```
@@ -36,74 +37,74 @@ The `paramsparser` module provides a comprehensive set of methods for retrieving
### Basic Retrieval
- `get(key string) !string`: Retrieves a string value by key. Returns an error if the key does not exist.
- `get_default(key string, defval string) !string`: Retrieves a string value by key, or returns `defval` if the key is not found.
- `exists(key string) bool`: Checks if a keyword argument (`key:value`) exists.
- `exists_arg(key string) bool`: Checks if an argument (value without a key) exists.
- `get(key string) !string`: Retrieves a string value by key. Returns an error if the key does not exist.
- `get_default(key string, defval string) !string`: Retrieves a string value by key, or returns `defval` if the key is not found.
- `exists(key string) bool`: Checks if a keyword argument (`key:value`) exists.
- `exists_arg(key string) bool`: Checks if an argument (value without a key) exists.
### Argument Retrieval (Positional)
- `get_arg(nr int) !string`: Retrieves an argument by its 0-based index. Returns an error if the index is out of bounds.
- `get_arg_default(nr int, defval string) !string`: Retrieves an argument by index, or returns `defval` if the index is out of bounds.
- `get_arg(nr int) !string`: Retrieves an argument by its 0-based index. Returns an error if the index is out of bounds.
- `get_arg_default(nr int, defval string) !string`: Retrieves an argument by index, or returns `defval` if the index is out of bounds.
### Type-Specific Retrieval
- `get_int(key string) !int`: Converts and retrieves an integer (int32).
- `get_int_default(key string, defval int) !int`: Retrieves an integer with a default.
- `get_u32(key string) !u32`: Converts and retrieves an unsigned 32-bit integer.
- `get_u32_default(key string, defval u32) !u32`: Retrieves a u32 with a default.
- `get_u64(key string) !u64`: Converts and retrieves an unsigned 64-bit integer.
- `get_u64_default(key string, defval u64) !u64`: Retrieves a u64 with a default.
- `get_u8(key string) !u8`: Converts and retrieves an unsigned 8-bit integer.
- `get_u8_default(key string, defval u8) !u8`: Retrieves a u8 with a default.
- `get_float(key string) !f64`: Converts and retrieves a 64-bit float.
- `get_float_default(key string, defval f64) !f64`: Retrieves a float with a default.
- `get_percentage(key string) !f64`: Converts a percentage string (e.g., "80%") to a float (0.8).
- `get_percentage_default(key string, defval string) !f64`: Retrieves a percentage with a default.
- `get_int(key string) !int`: Converts and retrieves an integer (int32).
- `get_int_default(key string, defval int) !int`: Retrieves an integer with a default.
- `get_u32(key string) !u32`: Converts and retrieves an unsigned 32-bit integer.
- `get_u32_default(key string, defval u32) !u32`: Retrieves a u32 with a default.
- `get_u64(key string) !u64`: Converts and retrieves an unsigned 64-bit integer.
- `get_u64_default(key string, defval u64) !u64`: Retrieves a u64 with a default.
- `get_u8(key string) !u8`: Converts and retrieves an unsigned 8-bit integer.
- `get_u8_default(key string, defval u8) !u8`: Retrieves a u8 with a default.
- `get_float(key string) !f64`: Converts and retrieves a 64-bit float.
- `get_float_default(key string, defval f64) !f64`: Retrieves a float with a default.
- `get_percentage(key string) !f64`: Converts a percentage string (e.g., "80%") to a float (0.8).
- `get_percentage_default(key string, defval string) !f64`: Retrieves a percentage with a default.
### Boolean Retrieval
- `get_default_true(key string) bool`: Returns `true` if the value is empty, "1", "true", "y", or "yes". Otherwise `false`.
- `get_default_false(key string) bool`: Returns `false` if the value is empty, "0", "false", "n", or "no". Otherwise `true`.
- `get_default_true(key string) bool`: Returns `true` if the value is empty, "1", "true", "y", or "yes". Otherwise `false`.
- `get_default_false(key string) bool`: Returns `false` if the value is empty, "0", "false", "n", or "no". Otherwise `true`.
### List Retrieval
Lists are typically comma-separated strings (e.g., `users: "john,jane,bob"`).
- `get_list(key string) ![]string`: Retrieves a list of strings.
- `get_list_default(key string, def []string) ![]string`: Retrieves a list of strings with a default.
- `get_list_int(key string) ![]int`: Retrieves a list of integers.
- `get_list_int_default(key string, def []int) []int`: Retrieves a list of integers with a default.
- `get_list_f32(key string) ![]f32`: Retrieves a list of 32-bit floats.
- `get_list_f32_default(key string, def []f32) []f32`: Retrieves a list of f32 with a default.
- `get_list_f64(key string) ![]f64`: Retrieves a list of 64-bit floats.
- `get_list_f64_default(key string, def []f64) []f64`: Retrieves a list of f64 with a default.
- `get_list_i8(key string) ![]i8`: Retrieves a list of 8-bit signed integers.
- `get_list_i8_default(key string, def []i8) []i8`: Retrieves a list of i8 with a default.
- `get_list_i16(key string) ![]i16`: Retrieves a list of 16-bit signed integers.
- `get_list_i16_default(key string, def []i16) []i16`: Retrieves a list of i16 with a default.
- `get_list_i64(key string) ![]i64`: Retrieves a list of 64-bit signed integers.
- `get_list_i64_default(key string, def []i64) []i64`: Retrieves a list of i64 with a default.
- `get_list_u16(key string) ![]u16`: Retrieves a list of 16-bit unsigned integers.
- `get_list_u16_default(key string, def []u16) []u16`: Retrieves a list of u16 with a default.
- `get_list_u32(key string) ![]u32`: Retrieves a list of 32-bit unsigned integers.
- `get_list_u32_default(key string, def []u32) []u32`: Retrieves a list of u32 with a default.
- `get_list_u64(key string) ![]u64`: Retrieves a list of 64-bit unsigned integers.
- `get_list_u64_default(key string, def []u64) []u64`: Retrieves a list of u64 with a default.
- `get_list_namefix(key string) ![]string`: Retrieves a list of strings, normalizing each item (e.g., "My Name" -> "my_name").
- `get_list_namefix_default(key string, def []string) ![]string`: Retrieves a list of name-fixed strings with a default.
- `get_list(key string) ![]string`: Retrieves a list of strings.
- `get_list_default(key string, def []string) ![]string`: Retrieves a list of strings with a default.
- `get_list_int(key string) ![]int`: Retrieves a list of integers.
- `get_list_int_default(key string, def []int) []int`: Retrieves a list of integers with a default.
- `get_list_f32(key string) ![]f32`: Retrieves a list of 32-bit floats.
- `get_list_f32_default(key string, def []f32) []f32`: Retrieves a list of f32 with a default.
- `get_list_f64(key string) ![]f64`: Retrieves a list of 64-bit floats.
- `get_list_f64_default(key string, def []f64) []f64`: Retrieves a list of f64 with a default.
- `get_list_i8(key string) ![]i8`: Retrieves a list of 8-bit signed integers.
- `get_list_i8_default(key string, def []i8) []i8`: Retrieves a list of i8 with a default.
- `get_list_i16(key string) ![]i16`: Retrieves a list of 16-bit signed integers.
- `get_list_i16_default(key string, def []i16) []i16`: Retrieves a list of i16 with a default.
- `get_list_i64(key string) ![]i64`: Retrieves a list of 64-bit signed integers.
- `get_list_i64_default(key string, def []i64) []i64`: Retrieves a list of i64 with a default.
- `get_list_u16(key string) ![]u16`: Retrieves a list of 16-bit unsigned integers.
- `get_list_u16_default(key string, def []u16) []u16`: Retrieves a list of u16 with a default.
- `get_list_u32(key string) ![]u32`: Retrieves a list of 32-bit unsigned integers.
- `get_list_u32_default(key string, def []u32) []u32`: Retrieves a list of u32 with a default.
- `get_list_u64(key string) ![]u64`: Retrieves a list of 64-bit unsigned integers.
- `get_list_u64_default(key string, def []u64) []u64`: Retrieves a list of u64 with a default.
- `get_list_namefix(key string) ![]string`: Retrieves a list of strings, normalizing each item (e.g., "My Name" -> "my_name").
- `get_list_namefix_default(key string, def []string) ![]string`: Retrieves a list of name-fixed strings with a default.
### Specialized Retrieval
- `get_map() map[string]string`: Returns all parameters as a map.
- `get_path(key string) !string`: Retrieves a path string.
- `get_path_create(key string) !string`: Retrieves a path string, creating the directory if it doesn't exist.
- `get_from_hashmap(key string, defval string, hashmap map[string]string) !string`: Retrieves a value from a provided hashmap based on the parameter's value.
- `get_storagecapacity_in_bytes(key string) !u64`: Converts storage capacity strings (e.g., "10 GB", "500 MB") to bytes (u64).
- `get_storagecapacity_in_bytes_default(key string, defval u64) !u64`: Retrieves storage capacity in bytes with a default.
- `get_storagecapacity_in_gigabytes(key string) !u64`: Converts storage capacity strings to gigabytes (u64).
- `get_time(key string) !ourtime.OurTime`: Parses a time string (relative or absolute) into an `ourtime.OurTime` object.
- `get_time_default(key string, defval ourtime.OurTime) !ourtime.OurTime`: Retrieves time with a default.
- `get_time_interval(key string) !Duration`: Parses a time interval string into a `Duration` object.
- `get_timestamp(key string) !Duration`: Parses a timestamp string into a `Duration` object.
- `get_timestamp_default(key string, defval Duration) !Duration`: Retrieves a timestamp with a default.
- `get_map() map[string]string`: Returns all parameters as a map.
- `get_path(key string) !string`: Retrieves a path string.
- `get_path_create(key string) !string`: Retrieves a path string, creating the directory if it doesn't exist.
- `get_from_hashmap(key string, defval string, hashmap map[string]string) !string`: Retrieves a value from a provided hashmap based on the parameter's value.
- `get_storagecapacity_in_bytes(key string) !u64`: Converts storage capacity strings (e.g., "10 GB", "500 MB") to bytes (u64).
- `get_storagecapacity_in_bytes_default(key string, defval u64) !u64`: Retrieves storage capacity in bytes with a default.
- `get_storagecapacity_in_gigabytes(key string) !u64`: Converts storage capacity strings to gigabytes (u64).
- `get_time(key string) !ourtime.OurTime`: Parses a time string (relative or absolute) into an `ourtime.OurTime` object.
- `get_time_default(key string, defval ourtime.OurTime) !ourtime.OurTime`: Retrieves time with a default.
- `get_time_interval(key string) !Duration`: Parses a time interval string into a `Duration` object.
- `get_timestamp(key string) !Duration`: Parses a timestamp string into a `Duration` object.
- `get_timestamp_default(key string, defval Duration) !Duration`: Retrieves a timestamp with a default.

View File

@@ -14,11 +14,15 @@ The pathlib module provides a comprehensive interface for handling file system o
## Basic Usage
### Importing pathlib
```v
import freeflowuniverse.herolib.core.pathlib
import incubaid.herolib.core.pathlib
```
### Creating Path Objects
This will figure out if the path is a dir, file and if it exists.
```v
// Create a Path object for a file
mut file_path := pathlib.get("path/to/file.txt")
@@ -27,7 +31,10 @@ mut file_path := pathlib.get("path/to/file.txt")
mut dir_path := pathlib.get("path/to/directory")
```
if you know in advance if you expect a dir or file its better to use `pathlib.get_dir(path:...,create:true)` or `pathlib.get_file(path:...,create:true)`.
### Basic Path Operations
```v
// Get absolute path
abs_path := file_path.absolute()
@@ -44,6 +51,7 @@ if file_path.exists() {
## Path Properties and Methods
### Path Types
```v
// Check if path is a file
if file_path.is_file() {
@@ -62,6 +70,7 @@ if file_path.is_link() {
```
### Path Normalization
```v
// Normalize path (remove extra slashes, resolve . and ..)
normalized_path := file_path.path_normalize()
@@ -76,6 +85,7 @@ name_no_ext := file_path.name_no_ext()
## File and Directory Operations
### File Operations
```v
// Write to file
file_path.write("Content to write")!
@@ -88,6 +98,7 @@ file_path.delete()!
```
### Directory Operations
```v
// Create directory
mut dir := pathlib.get_dir(
@@ -103,6 +114,7 @@ dir.delete()!
```
### Symlink Operations
```v
// Create symlink
file_path.link("path/to/symlink", delete_exists: true)!
@@ -114,12 +126,14 @@ real_path := file_path.realpath()
## Advanced Operations
### Path Copying
```v
// Copy file to destination
file_path.copy(dest: "path/to/destination")!
```
### Recursive Operations
```v
// List directory recursively
mut recursive_list := dir.list(recursive: true)!
@@ -129,6 +143,7 @@ dir.delete()!
```
### Path Filtering
```v
// List files matching pattern
mut filtered_list := dir.list(
@@ -140,6 +155,7 @@ mut filtered_list := dir.list(
## Best Practices
### Error Handling
```v
if file_path.exists() {
// Safe to operate
@@ -147,4 +163,3 @@ if file_path.exists() {
// Handle missing file
}
```

View File

@@ -4,17 +4,17 @@ The `redisclient` module in Herolib provides a comprehensive client for interact
## Key Features
- **Direct Redis Commands**: Access to a wide range of Redis commands (strings, hashes, lists, keys, etc.).
- **Caching**: Built-in caching mechanism with namespace support and expiration.
- **Queues**: Simple queue implementation using Redis lists.
- **RPC**: Remote Procedure Call (RPC) functionality over Redis queues for inter-service communication.
- **Direct Redis Commands**: Access to a wide range of Redis commands (strings, hashes, lists, keys, etc.).
- **Caching**: Built-in caching mechanism with namespace support and expiration.
- **Queues**: Simple queue implementation using Redis lists.
- **RPC**: Remote Procedure Call (RPC) functionality over Redis queues for inter-service communication.
## Basic Usage
To get a Redis client instance, use `redisclient.core_get()`. By default, it connects to `127.0.0.1:6379`. You can specify a different address and port using the `RedisURL` struct.
```v
import freeflowuniverse.herolib.core.redisclient
import incubaid.herolib.core.redisclient
// Connect to default Redis instance (127.0.0.1:6379)
mut redis := redisclient.core_get()!
@@ -42,13 +42,13 @@ The `Redis` object provides methods for most standard Redis commands. Here are s
### String Commands
- `set(key string, value string) !`: Sets the string value of a key.
- `get(key string) !string`: Gets the string value of a key.
- `set_ex(key string, value string, ex string) !`: Sets a key with an expiration time in seconds.
- `incr(key string) !int`: Increments the integer value of a key by one.
- `decr(key string) !int`: Decrements the integer value of a key by one.
- `append(key string, value string) !int`: Appends a value to a key.
- `strlen(key string) !int`: Gets the length of the value stored in a key.
- `set(key string, value string) !`: Sets the string value of a key.
- `get(key string) !string`: Gets the string value of a key.
- `set_ex(key string, value string, ex string) !`: Sets a key with an expiration time in seconds.
- `incr(key string) !int`: Increments the integer value of a key by one.
- `decr(key string) !int`: Decrements the integer value of a key by one.
- `append(key string, value string) !int`: Appends a value to a key.
- `strlen(key string) !int`: Gets the length of the value stored in a key.
```v
redis.set('counter', '10')!
@@ -58,11 +58,11 @@ val := redis.get('counter')! // "11"
### Hash Commands
- `hset(key string, skey string, value string) !`: Sets the string value of a hash field.
- `hget(key string, skey string) !string`: Gets the value of a hash field.
- `hgetall(key string) !map[string]string`: Gets all fields and values in a hash.
- `hexists(key string, skey string) !bool`: Checks if a hash field exists.
- `hdel(key string, skey string) !int`: Deletes one or more hash fields.
- `hset(key string, skey string, value string) !`: Sets the string value of a hash field.
- `hget(key string, skey string) !string`: Gets the value of a hash field.
- `hgetall(key string) !map[string]string`: Gets all fields and values in a hash.
- `hexists(key string, skey string) !bool`: Checks if a hash field exists.
- `hdel(key string, skey string) !int`: Deletes one or more hash fields.
```v
redis.hset('user:1', 'name', 'John Doe')!
@@ -73,12 +73,12 @@ user_data := redis.hgetall('user:1')! // map['name':'John Doe', 'email':'john@ex
### List Commands
- `lpush(key string, element string) !int`: Inserts all specified values at the head of the list stored at key.
- `rpush(key string, element string) !int`: Inserts all specified values at the tail of the list stored at key.
- `lpop(key string) !string`: Removes and returns the first element of the list stored at key.
- `rpop(key string) !string`: Removes and returns the last element of the list stored at key.
- `llen(key string) !int`: Gets the length of a list.
- `lrange(key string, start int, end int) ![]resp.RValue`: Gets a range of elements from a list.
- `lpush(key string, element string) !int`: Inserts all specified values at the head of the list stored at key.
- `rpush(key string, element string) !int`: Inserts all specified values at the tail of the list stored at key.
- `lpop(key string) !string`: Removes and returns the first element of the list stored at key.
- `rpop(key string) !string`: Removes and returns the last element of the list stored at key.
- `llen(key string) !int`: Gets the length of a list.
- `lrange(key string, start int, end int) ![]resp.RValue`: Gets a range of elements from a list.
```v
redis.lpush('mylist', 'item1')!
@@ -88,8 +88,8 @@ first_item := redis.lpop('mylist')! // "item1"
### Set Commands
- `sadd(key string, members []string) !int`: Adds the specified members to the set stored at key.
- `smismember(key string, members []string) ![]int`: Returns if member is a member of the set stored at key.
- `sadd(key string, members []string) !int`: Adds the specified members to the set stored at key.
- `smismember(key string, members []string) ![]int`: Returns if member is a member of the set stored at key.
```v
redis.sadd('myset', ['member1', 'member2'])!
@@ -98,13 +98,13 @@ is_member := redis.smismember('myset', ['member1', 'member3'])! // [1, 0]
### Key Management
- `keys(pattern string) ![]string`: Finds all keys matching the given pattern.
- `del(key string) !int`: Deletes a key.
- `expire(key string, seconds int) !int`: Sets a key's time to live in seconds.
- `ttl(key string) !int`: Gets the time to live for a key in seconds.
- `flushall() !`: Deletes all the keys of all the existing databases.
- `flushdb() !`: Deletes all the keys of the currently selected database.
- `selectdb(database int) !`: Changes the selected database.
- `keys(pattern string) ![]string`: Finds all keys matching the given pattern.
- `del(key string) !int`: Deletes a key.
- `expire(key string, seconds int) !int`: Sets a key's time to live in seconds.
- `ttl(key string) !int`: Gets the time to live for a key in seconds.
- `flushall() !`: Deletes all the keys of all the existing databases.
- `flushdb() !`: Deletes all the keys of the currently selected database.
- `selectdb(database int) !`: Changes the selected database.
```v
redis.set('temp_key', 'value')!
@@ -116,7 +116,7 @@ redis.expire('temp_key', 60)! // Expires in 60 seconds
The `RedisCache` struct provides a convenient way to implement caching using Redis.
```v
import freeflowuniverse.herolib.core.redisclient
import incubaid.herolib.core.redisclient
mut redis := redisclient.core_get()!
mut cache := redis.cache('my_app_cache')
@@ -145,7 +145,7 @@ cache.reset()!
The `RedisQueue` struct provides a simple queue mechanism using Redis lists.
```v
import freeflowuniverse.herolib.core.redisclient
import incubaid.herolib.core.redisclient
import time
mut redis := redisclient.core_get()!
@@ -169,7 +169,7 @@ task2 := my_queue.pop()!
The `RedisRpc` struct enables Remote Procedure Call (RPC) over Redis, allowing services to communicate by sending messages to queues and waiting for responses.
```v
import freeflowuniverse.herolib.core.redisclient
import incubaid.herolib.core.redisclient
import json
import time
@@ -201,4 +201,4 @@ response := rpc_client.call(
// In a real application, this would be in a loop or a background worker
// return_queue_name := rpc_client.process(my_rpc_processor, timeout: 1000)!
// result := rpc_client.result(1000, return_queue_name)!
// println('Processed result: ${result}')
// println('Processed result: ${result}')

View File

@@ -2,96 +2,124 @@
The `texttools` module provides a comprehensive set of utilities for text manipulation and processing.
## Functions and Examples:
## Functions and Examples
```v
import freeflowuniverse.herolib.core.texttools
import incubaid.herolib.core.texttools
assert hello_world == texttools.name_fix("Hello World!")
```
### Name/Path Processing
* `name_fix(name string) string`: Normalizes filenames and paths.
* `name_fix_keepspace(name string) !string`: Like name_fix but preserves spaces.
* `name_fix_no_ext(name_ string) string`: Removes file extension.
* `name_fix_snake_to_pascal(name string) string`: Converts snake_case to PascalCase.
* `name_fix(name string) string`: Normalizes filenames and paths.
* `name_fix_keepspace(name string) !string`: Like name_fix but preserves spaces.
* `name_fix_no_ext(name_ string) string`: Removes file extension.
* `name_fix_snake_to_pascal(name string) string`: Converts snake_case to PascalCase.
```v
name := texttools.name_fix_snake_to_pascal("hello_world") // Result: "HelloWorld"
```
* `snake_case(name string) string`: Converts PascalCase to snake_case.
* `snake_case(name string) string`: Converts PascalCase to snake_case.
```v
name := texttools.snake_case("HelloWorld") // Result: "hello_world"
```
* `name_split(name string) !(string, string)`: Splits name into site and page components.
* `name_split(name string) !(string, string)`: Splits name into site and page components.
### Text Cleaning
* `name_clean(r string) string`: Normalizes names by removing special characters.
* `name_clean(r string) string`: Normalizes names by removing special characters.
```v
name := texttools.name_clean("Hello@World!") // Result: "HelloWorld"
```
* `ascii_clean(r string) string`: Removes all non-ASCII characters.
* `remove_empty_lines(text string) string`: Removes empty lines from text.
* `ascii_clean(r string) string`: Removes all non-ASCII characters.
* `remove_empty_lines(text string) string`: Removes empty lines from text.
```v
text := texttools.remove_empty_lines("line1\n\nline2\n\n\nline3") // Result: "line1\nline2\nline3"
```
* `remove_double_lines(text string) string`: Removes consecutive empty lines.
* `remove_empty_js_blocks(text string) string`: Removes empty code blocks (```...```).
* `remove_double_lines(text string) string`: Removes consecutive empty lines.
* `remove_empty_js_blocks(text string) string`: Removes empty code blocks (```...```).
### Command Line Parsing
* `cmd_line_args_parser(text string) ![]string`: Parses command line arguments with support for quotes and escaping.
* `cmd_line_args_parser(text string) ![]string`: Parses command line arguments with support for quotes and escaping.
```v
args := texttools.cmd_line_args_parser("'arg with spaces' --flag=value") // Result: ['arg with spaces', '--flag=value']
```
* `text_remove_quotes(text string) string`: Removes quoted sections from text.
* `check_exists_outside_quotes(text string, items []string) bool`: Checks if items exist in text outside of quotes.
* `text_remove_quotes(text string) string`: Removes quoted sections from text.
* `check_exists_outside_quotes(text string, items []string) bool`: Checks if items exist in text outside of quotes.
### Text Expansion
* `expand(txt_ string, l int, expand_with string) string`: Expands text to a specified length with a given character.
* `expand(txt_ string, l int, expand_with string) string`: Expands text to a specified length with a given character.
### Indentation
* `indent(text string, prefix string) string`: Adds indentation prefix to each line.
* `indent(text string, prefix string) string`: Adds indentation prefix to each line.
```v
text := texttools.indent("line1\nline2", " ") // Result: " line1\n line2\n"
```
* `dedent(text string) string`: Removes common leading whitespace from every line.
* `dedent(text string) string`: Removes common leading whitespace from every line.
```v
text := texttools.dedent(" line1\n line2") // Result: "line1\nline2"
```
### String Validation
* `is_int(text string) bool`: Checks if text contains only digits.
* `is_upper_text(text string) bool`: Checks if text contains only uppercase letters.
* `is_int(text string) bool`: Checks if text contains only digits.
* `is_upper_text(text string) bool`: Checks if text contains only uppercase letters.
### Multiline Processing
* `multiline_to_single(text string) !string`: Converts multiline text to a single line with proper escaping.
* `multiline_to_single(text string) !string`: Converts multiline text to a single line with proper escaping.
### Text Splitting
* `split_smart(t string, delimiter_ string) []string`: Intelligent string splitting that respects quotes.
* `split_smart(t string, delimiter_ string) []string`: Intelligent string splitting that respects quotes.
### Tokenization
* `tokenize(text_ string) TokenizerResult`: Tokenizes text into meaningful parts.
* `text_token_replace(text string, tofind string, replacewith string) !string`: Replaces tokens in text.
* `tokenize(text_ string) TokenizerResult`: Tokenizes text into meaningful parts.
* `text_token_replace(text string, tofind string, replacewith string) !string`: Replaces tokens in text.
### Version Parsing
* `version(text_ string) int`: Converts version strings to comparable integers.
* `version(text_ string) int`: Converts version strings to comparable integers.
```v
ver := texttools.version("v0.4.36") // Result: 4036
ver = texttools.version("v1.4.36") // Result: 1004036
```
### Formatting
* `format_rfc1123(t time.Time) string`: Formats a time.Time object into RFC 1123 format.
* `format_rfc1123(t time.Time) string`: Formats a time.Time object into RFC 1123 format.
### Array Operations
* `to_array(r string) []string`: Converts a comma or newline separated list to an array of strings.
* `to_array(r string) []string`: Converts a comma or newline separated list to an array of strings.
```v
text := "item1,item2,item3"
array := texttools.to_array(text) // Result: ['item1', 'item2', 'item3']
```
* `to_array_int(r string) []int`: Converts a text list to an array of integers.
* `to_map(mapstring string, line string, delimiter_ string) map[string]string`: Intelligent mapping of a line to a map based on a template.
* `to_array_int(r string) []int`: Converts a text list to an array of integers.
* `to_map(mapstring string, line string, delimiter_ string) map[string]string`: Intelligent mapping of a line to a map based on a template.
```v
r := texttools.to_map("name,-,-,-,-,pid,-,-,-,-,path",
"root 304 0.0 0.0 408185328 1360 ?? S 16Dec23 0:34.06 /usr/sbin/distnoted")

View File

@@ -4,8 +4,8 @@ has mechanisms to print better to console, see the methods below
import as
```vlang
import freeflowuniverse.herolib.ui.console
```v
import incubaid.herolib.ui.console
```
@@ -24,23 +24,23 @@ fn color_fg(c ForegroundColor) string
struct PrintArgs {
pub mut:
foreground ForegroundColor
background BackgroundColor
text string
style Style
reset_before bool = true
reset_after bool = true
foreground ForegroundColor
background BackgroundColor
text string
style Style
reset_before bool = true
reset_after bool = true
}
fn cprint(args PrintArgs)
// print with colors, reset...
// ```
// foreground ForegroundColor
// background BackgroundColor
// text string
// style Style
// reset_before bool = true
// reset_after bool = true
// foreground ForegroundColor
// background BackgroundColor
// text string
// style Style
// reset_before bool = true
// reset_after bool = true
// ```
fn cprintln(args_ PrintArgs)
@@ -95,11 +95,11 @@ Is used to ask feedback to users
struct UIConsole {
pub mut:
x_max int = 80
y_max int = 60
prev_lf bool
prev_title bool
prev_item bool
x_max int = 80
y_max int = 60
prev_lf bool
prev_title bool
prev_item bool
}
//DropDownArgs:
@@ -150,51 +150,51 @@ fn (mut c UIConsole) status() string
```v
enum BackgroundColor {
default_color = 49 // 'default' is a reserved keyword in V
black = 40
red = 41
green = 42
yellow = 43
blue = 44
magenta = 45
cyan = 46
light_gray = 47
dark_gray = 100
light_red = 101
light_green = 102
light_yellow = 103
light_blue = 104
light_magenta = 105
light_cyan = 106
white = 107
default_color = 49 // 'default' is a reserved keyword in V
black = 40
red = 41
green = 42
yellow = 43
blue = 44
magenta = 45
cyan = 46
light_gray = 47
dark_gray = 100
light_red = 101
light_green = 102
light_yellow = 103
light_blue = 104
light_magenta = 105
light_cyan = 106
white = 107
}
enum ForegroundColor {
default_color = 39 // 'default' is a reserved keyword in V
white = 97
black = 30
red = 31
green = 32
yellow = 33
blue = 34
magenta = 35
cyan = 36
light_gray = 37
dark_gray = 90
light_red = 91
light_green = 92
light_yellow = 93
light_blue = 94
light_magenta = 95
light_cyan = 96
default_color = 39 // 'default' is a reserved keyword in V
white = 97
black = 30
red = 31
green = 32
yellow = 33
blue = 34
magenta = 35
cyan = 36
light_gray = 37
dark_gray = 90
light_red = 91
light_green = 92
light_yellow = 93
light_blue = 94
light_magenta = 95
light_cyan = 96
}
enum Style {
normal = 99
bold = 1
dim = 2
underline = 4
blink = 5
reverse = 7
hidden = 8
normal = 99
bold = 1
dim = 2
underline = 4
blink = 5
reverse = 7
hidden = 8
}
```

View File

@@ -2,14 +2,14 @@
this is how we want example scripts to be, see the first line
```vlang
```v
#!/usr/bin/env -S v -cg -gc none -cc tcc -d use_openssl -enable-globals run
import freeflowuniverse.herolib...
import incubaid.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

View File

@@ -0,0 +1,165 @@
V allows for easily using text templates, expanded at compile time to
V functions, that efficiently produce text output. This is especially
useful for templated HTML views, but the mechanism is general enough
to be used for other kinds of text output also.
# Template directives
Each template directive begins with an `@` sign.
Some directives contain a `{}` block, others only have `''` (string) parameters.
Newlines on the beginning and end are ignored in `{}` blocks,
otherwise this (see [if](#if) for this syntax):
```html
@if bool_val {
<span>This is shown if bool_val is true</span>
}
```
... would output:
```html
<span>This is shown if bool_val is true</span>
```
... which is less readable.
## if
The if directive, consists of three parts, the `@if` tag, the condition (same syntax like in V)
and the `{}` block, where you can write html, which will be rendered if the condition is true:
```
@if <condition> {}
```
### Example
```html
@if bool_val {
<span>This is shown if bool_val is true</span>
}
```
One-liner:
```html
@if bool_val { <span>This is shown if bool_val is true</span> }
```
The first example would result in:
```html
<span>This is shown if bool_val is true</span>
```
... while the one-liner results in:
```html
<span>This is shown if bool_val is true</span>
```
## for
The for directive consists of three parts, the `@for` tag,
the condition (same syntax like in V) and the `{}` block,
where you can write text, rendered for each iteration of the loop:
```
@for <condition> {}
```
### Example for @for
```html
@for i, val in my_vals {
<span>$i - $val</span>
}
```
One-liner:
```html
@for i, val in my_vals { <span>$i - $val</span> }
```
The first example would result in:
```html
<span>0 - "First"</span>
<span>1 - "Second"</span>
<span>2 - "Third"</span>
...
```
... while the one-liner results in:
```html
<span>0 - "First"</span>
<span>1 - "Second"</span>
<span>2 - "Third"</span>
...
```
You can also write (and all other for condition syntaxes that are allowed in V):
```html
@for i = 0; i < 5; i++ {
<span>$i</span>
}
```
## include
The include directive is for including other html files (which will be processed as well)
and consists of two parts, the `@include` tag and a following `'<path>'` string.
The path parameter is relative to the template file being called.
### Example for the folder structure of a project using templates:
```
Project root
/templates
- index.html
/headers
- base.html
```
`index.html`
```html
<div>@include 'header/base'</div>
```
> Note that there shouldn't be a file suffix,
> it is automatically appended and only allows `html` files.
## js
The js directive consists of two parts, the `@js` tag and `'<path>'` string,
where you can insert your src
```
@js '<url>'
```
### Example for the @js directive:
```html
@js 'myscripts.js'
```
# Variables
All variables, which are declared before the $tmpl can be used through the `@{my_var}` syntax.
It's also possible to use properties of structs here like `@{my_struct.prop}`.
# Escaping
The `@` symbol starts a template directive. If you need to use `@` as a regular
character within a template, escape it by using a double `@` like this: `@@`.

View File

@@ -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

View File

@@ -0,0 +1,819 @@
# HeroModels Implementation Guide
This guide provides comprehensive instructions for creating new models in the HeroModels system, including best practices for model structure, serialization/deserialization, testing, and integration with the HeroModels factory.
## Table of Contents
1. [Model Structure Overview](#model-structure-overview)
2. [Creating a New Model](#creating-a-new-model)
3. [Serialization and Deserialization](#serialization-and-deserialization)
4. [Database Operations](#database-operations)
5. [API Handler Implementation](#api-handler-implementation)
6. [Testing Models](#testing-models)
7. [Integration with Factory](#integration-with-factory)
8. [Advanced Features](#advanced-features)
9. [Best Practices](#best-practices)
10. [Example Implementation](#example-implementation)
## Model Structure Overview
Each model in the HeroModels system consists of several components:
1. **Model Struct**: The core data structure inheriting from `db.Base`
2. **DB Wrapper Struct**: Provides database operations for the model
3. **Argument Struct**: Used for creating and updating model instances
4. **API Handler Function**: Handles RPC calls for the model
5. **List Arguments Struct**: Used for filtering when listing instances
### Directory Structure
```
lib/hero/heromodels/
├── model_name.v # Main model file
├── model_name_test.v # Tests for the model
└── factory.v # Factory integration
```
## Creating a New Model
### 1. Define the Model Struct
Create a new file `model_name.v` in the `lib/hero/heromodels` directory.
```v
module heromodels
import incubaid.herolib.core.db
import incubaid.herolib.core.encoder
import incubaid.herolib.core.ourtime
import incubaid.herolib.core.jsonrpc { Response }
import json
// Model struct - inherits from db.Base
pub struct ModelName {
pub mut:
db.Base // Inherit from db.Base
name string
description string
created_at u64
updated_at u64
// Add additional fields as needed
}
// TypeName returns the type name used for serialization
pub fn (self ModelName) type_name() string {
return 'heromodels.ModelName'
}
```
### 2. Define the Argument Struct for Model Creation/Updates
```v
// Argument struct for creating/updating models with params attribute
@[params]
pub struct ModelNameArg {
pub mut:
id u32 // Optional for updates, ignored for creation
name string @[required] // Required field
description string
// Add additional fields as needed
}
```
### 3. Define the List Arguments Struct for Filtering
```v
// Arguments for filtering when listing models
@[params]
pub struct ModelNameListArg {
pub mut:
// Add filter fields (e.g., status, type, etc.)
limit int = 100 // Default limit
}
```
### 4. Create the DB Wrapper Struct
```v
// DB Wrapper struct for database operations
pub struct DBModelName {
pub mut:
db &db.DB
}
```
## Serialization and Deserialization
Implement the `dump` and `load` methods for serialization/deserialization.
### Dump Method (Serialization)
```v
// Dump serializes the model to the encoder
pub fn (self ModelName) dump(mut e encoder.Encoder) ! {
// Always dump the Base first
self.Base.dump(mut e)!
// Dump model-specific fields in the same order they will be loaded
e.add_string(self.name)!
e.add_string(self.description)!
e.add_u64(self.created_at)!
e.add_u64(self.updated_at)!
// Add more fields in the exact order they should be loaded
}
```
### Load Method (Deserialization)
```v
// Load deserializes the model from the decoder
pub fn (mut self DBModelName) load(mut obj ModelName, mut d encoder.Decoder) ! {
// Always load the Base first
obj.Base.load(mut d)!
// Load model-specific fields in the same order they were dumped
obj.name = d.get_string()!
obj.description = d.get_string()!
obj.created_at = d.get_u64()!
obj.updated_at = d.get_u64()!
// Add more fields in the exact order they were dumped
}
```
## Database Operations
Implement the standard CRUD operations and additional methods.
### New Instance Creation
```v
// Create a new model instance from arguments
pub fn (mut self DBModelName) new(args ModelNameArg) !ModelName {
mut o := ModelName{
name: args.name
description: args.description
// Initialize other fields
created_at: ourtime.now().unix()
updated_at: ourtime.now().unix()
}
// Additional initialization logic
return o
}
```
### Set (Create or Update)
```v
// Save or update a model instance
pub fn (mut self DBModelName) set(o ModelName) !ModelName {
return self.db.set[ModelName](o)!
}
```
### Get
```v
// Retrieve a model instance by ID
pub fn (mut self DBModelName) get(id u32) !ModelName {
mut o, data := self.db.get_data[ModelName](id)!
mut e_decoder := encoder.decoder_new(data)
self.load(mut o, mut e_decoder)!
return o
}
```
### Delete
```v
// Delete a model instance by ID
pub fn (mut self DBModelName) delete(id u32) !bool {
// Check if the item exists before trying to delete
if !self.db.exists[ModelName](id)! {
return false
}
self.db.delete[ModelName](id)!
return true
}
```
### Exist
```v
// Check if a model instance exists by ID
pub fn (mut self DBModelName) exist(id u32) !bool {
return self.db.exists[ModelName](id)!
}
```
### List with Filtering
```v
// List model instances with optional filtering
pub fn (mut self DBModelName) list(args ModelNameListArg) ![]ModelName {
// Get all instances
all_items := self.db.list[ModelName]()!.map(self.get(it)!)
// Apply filters
mut filtered_items := []ModelName{}
for item in all_items {
// Apply your filter conditions here
// Example:
// if args.some_filter && item.some_property != args.filter_value {
// continue
// }
filtered_items << item
}
// Apply limit
mut limit := args.limit
if limit > 100 {
limit = 100
}
if filtered_items.len > limit {
return filtered_items[..limit]
}
return filtered_items
}
```
## API Handler Implementation
Create the handler function for RPC requests.
```v
// Handler for RPC calls to this model
pub fn model_name_handle(mut f ModelsFactory, rpcid int, servercontext map[string]string, userref UserRef, method string, params string) !Response {
match method {
'get' {
id := db.decode_u32(params)!
res := f.model_name.get(id)!
return new_response(rpcid, json.encode_pretty(res))
}
'set' {
mut args := db.decode_generic[ModelNameArg](params)!
mut o := f.model_name.new(args)!
if args.id != 0 {
o.id = args.id
}
o = f.model_name.set(o)!
return new_response_int(rpcid, int(o.id))
}
'delete' {
id := db.decode_u32(params)!
deleted := f.model_name.delete(id)!
if deleted {
return new_response_true(rpcid)
} else {
return new_error(rpcid,
code: 404
message: 'ModelName with ID ${id} not found'
)
}
}
'exist' {
id := db.decode_u32(params)!
if f.model_name.exist(id)! {
return new_response_true(rpcid)
} else {
return new_response_false(rpcid)
}
}
'list' {
args := db.decode_generic[ModelNameListArg](params)!
res := f.model_name.list(args)!
return new_response(rpcid, json.encode_pretty(res))
}
else {
return new_error(rpcid,
code: 32601
message: 'Method ${method} not found on model_name'
)
}
}
}
```
## Testing Models
Create a `model_name_test.v` file to test your model.
```v
module heromodels
fn test_model_name_crud() ! {
// Initialize DB for testing
mut mydb := db.new_test()!
mut db_model := DBModelName{
db: &mydb
}
// Create
mut args := ModelNameArg{
name: 'Test Model'
description: 'A test model'
}
mut model := db_model.new(args)!
model = db_model.set(model)!
model_id := model.id
// Verify ID assignment
assert model_id > 0
// Read
retrieved_model := db_model.get(model_id)!
assert retrieved_model.name == 'Test Model'
assert retrieved_model.description == 'A test model'
// Update
retrieved_model.description = 'Updated description'
updated_model := db_model.set(retrieved_model)!
assert updated_model.description == 'Updated description'
// Delete
deleted := db_model.delete(model_id)!
assert deleted == true
// Verify deletion
exists := db_model.exist(model_id)!
assert exists == false
}
fn test_model_name_type_name() ! {
// Initialize DB for testing
mut mydb := db.new_test()!
mut db_model := DBModelName{
db: &mydb
}
// Create a model
mut model := db_model.new(
name: 'Type Test'
description: 'Testing type_name'
)!
// Test type_name method
assert model.type_name() == 'heromodels.ModelName'
}
fn test_model_name_description() ! {
// Initialize DB for testing
mut mydb := db.new_test()!
mut db_model := DBModelName{
db: &mydb
}
// Create a model
mut model := db_model.new(
name: 'Description Test'
description: 'Testing description method'
)!
// Test description method for each methodname
assert model.description('set') == 'Create or update a model. Returns the ID of the model.'
assert model.description('get') == 'Retrieve a model by ID. Returns the model object.'
assert model.description('delete') == 'Delete a model by ID. Returns true if successful.'
assert model.description('exist') == 'Check if a model exists by ID. Returns true or false.'
assert model.description('list') == 'List all models. Returns an array of model objects.'
}
fn test_model_name_example() ! {
// Initialize DB for testing
mut mydb := db.new_test()!
mut db_model := DBModelName{
db: &mydb
}
// Create a model
mut model := db_model.new(
name: 'Example Test'
description: 'Testing example method'
)!
// Test example method for each methodname
set_call, set_result := model.example('set')
// Assert expected call and result format
get_call, get_result := model.example('get')
// Assert expected call and result format
delete_call, delete_result := model.example('delete')
// Assert expected call and result format
exist_call, exist_result := model.example('exist')
// Assert expected call and result format
list_call, list_result := model.example('list')
// Assert expected call and result format
}
fn test_model_name_encoding_decoding() ! {
// Initialize DB for testing
mut mydb := db.new_test()!
mut db_model := DBModelName{
db: &mydb
}
// Create a model with all fields populated
mut args := ModelNameArg{
name: 'Encoding Test'
description: 'Testing encoding/decoding'
// Set other fields
}
mut model := db_model.new(args)!
// Save the model
model = db_model.set(model)!
model_id := model.id
// Retrieve and verify all fields were properly encoded/decoded
retrieved_model := db_model.get(model_id)!
// Verify all fields match the original
assert retrieved_model.name == 'Encoding Test'
assert retrieved_model.description == 'Testing encoding/decoding'
// Check other fields
}
```
## Integration with Factory
Update the `factory.v` file to include your new model.
### 1. Add the Model to the Factory Struct
```v
// In factory.v
pub struct ModelsFactory {
pub mut:
db &db.DB
user DBUser
group DBGroup
// Add your new model
model_name DBModelName
// Other models...
rpc_handler &jsonrpc.Handler
}
```
### 2. Initialize the Model in the Factory New Method
```v
// In factory.v, in the new() function
pub fn new(args ModelsFactoryArgs) !&ModelsFactory {
// Existing code...
mut f := ModelsFactory{
db: &mydb
user: DBUser{
db: &mydb
}
// Add your new model
model_name: DBModelName{
db: &mydb
}
// Other models...
rpc_handler: &h
}
// Existing code...
}
```
### 3. Add Handler Registration to the Factory API Handler
```v
// In factory.v, in the group_api_handler function
pub fn group_api_handler(rpcid int, servercontext map[string]string, actorname string, methodname string, params string) !jsonrpc.Response {
// Existing code...
match actorname {
// Existing cases...
'model_name' {
return model_name_handle(mut f, rpcid, servercontext, userref, methodname, params)!
}
// Existing cases...
else {
// Error handling
}
}
}
```
## Advanced Features
### Custom Methods
You can add custom methods to your model for specific business logic:
```v
// Add a custom method to the model
pub fn (mut self ModelName) custom_operation(param string) !string {
// Custom business logic
self.updated_at = ourtime.now().unix()
return 'Performed ${param} operation'
}
```
### Enhanced RPC Handling
Extend the RPC handler to support your custom methods:
```v
// In the model_name_handle function
match method {
// Standard CRUD methods...
'custom_operation' {
id := db.decode_u32(params)!
mut model := f.model_name.get(id)!
// Extract parameter from JSON
param_struct := json.decode(struct { param string }, params) or {
return new_error(rpcid,
code: 32602
message: 'Invalid parameters for custom_operation'
)
}
result := model.custom_operation(param_struct.param)!
model = f.model_name.set(model)! // Save changes
return new_response(rpcid, json.encode(result))
}
else {
// Error handling
}
}
```
## Best Practices
1. **Field Order**: Keep field ordering consistent between `dump` and `load` methods
2. **Error Handling**: Use the `!` operator consistently for error propagation
3. **Timestamp Management**: Initialize timestamps using `ourtime.now().unix()`
4. **Required Fields**: Mark mandatory fields with `@[required]` attribute
5. **Limits**: Enforce list limits (default 100)
6. **ID Handling**: Always check existence before operations like delete
7. **Validation**: Add validation in the `new` and `set` methods
8. **API Methods**: Implement the standard CRUD operations (get, set, delete, exist, list)
9. **Comments**: Document all fields and methods
10. **Testing**: Create comprehensive tests covering all methods
## Example Implementation
Here is a complete example of a simple "Project" model:
```v
module heromodels
import incubaid.herolib.core.db
import incubaid.herolib.core.encoder
import incubaid.herolib.core.ourtime
import incubaid.herolib.core.jsonrpc { Response }
import json
// Project model
pub struct Project {
pub mut:
db.Base // Inherit from db.Base
name string
description string
status ProjectStatus
owner_id u32
members []u32
created_at u64
updated_at u64
}
// Project status enum
pub enum ProjectStatus {
active
completed
archived
}
// TypeName for serialization
pub fn (self Project) type_name() string {
return 'heromodels.Project'
}
// Dump serializes the model
pub fn (self Project) dump(mut e encoder.Encoder) ! {
self.Base.dump(mut e)!
e.add_string(self.name)!
e.add_string(self.description)!
e.add_u8(u8(self.status))!
e.add_u32(self.owner_id)!
e.add_array_u32(self.members)!
e.add_u64(self.created_at)!
e.add_u64(self.updated_at)!
}
// Project argument struct
@[params]
pub struct ProjectArg {
pub mut:
id u32
name string @[required]
description string
status ProjectStatus = .active
owner_id u32 @[required]
members []u32
}
// Project list argument struct
@[params]
pub struct ProjectListArg {
pub mut:
status ProjectStatus
owner_id u32
limit int = 100
}
// DB wrapper struct
pub struct DBProject {
pub mut:
db &db.DB
}
// Load deserializes the model
pub fn (mut self DBProject) load(mut obj Project, mut d encoder.Decoder) ! {
obj.Base.load(mut d)!
obj.name = d.get_string()!
obj.description = d.get_string()!
obj.status = unsafe { ProjectStatus(d.get_u8()!) }
obj.owner_id = d.get_u32()!
obj.members = d.get_array_u32()!
obj.created_at = d.get_u64()!
obj.updated_at = d.get_u64()!
}
// Create a new Project
pub fn (mut self DBProject) new(args ProjectArg) !Project {
mut o := Project{
name: args.name
description: args.description
status: args.status
owner_id: args.owner_id
members: args.members
created_at: ourtime.now().unix()
updated_at: ourtime.now().unix()
}
return o
}
// Save or update a Project
pub fn (mut self DBProject) set(o Project) !Project {
return self.db.set[Project](o)!
}
// Get a Project by ID
pub fn (mut self DBProject) get(id u32) !Project {
mut o, data := self.db.get_data[Project](id)!
mut e_decoder := encoder.decoder_new(data)
self.load(mut o, mut e_decoder)!
return o
}
// Delete a Project by ID
pub fn (mut self DBProject) delete(id u32) !bool {
if !self.db.exists[Project](id)! {
return false
}
self.db.delete[Project](id)!
return true
}
// Check if a Project exists
pub fn (mut self DBProject) exist(id u32) !bool {
return self.db.exists[Project](id)!
}
// List Projects with filtering
pub fn (mut self DBProject) list(args ProjectListArg) ![]Project {
all_projects := self.db.list[Project]()!.map(self.get(it)!)
mut filtered_projects := []Project{}
for project in all_projects {
// Filter by status if provided
if args.status != .active && project.status != args.status {
continue
}
// Filter by owner_id if provided
if args.owner_id != 0 && project.owner_id != args.owner_id {
continue
}
filtered_projects << project
}
mut limit := args.limit
if limit > 100 {
limit = 100
}
if filtered_projects.len > limit {
return filtered_projects[..limit]
}
return filtered_projects
}
// API description method
pub fn (self Project) description(methodname string) string {
match methodname {
'set' { return 'Create or update a project. Returns the ID of the project.' }
'get' { return 'Retrieve a project by ID. Returns the project object.' }
'delete' { return 'Delete a project by ID. Returns true if successful.' }
'exist' { return 'Check if a project exists by ID. Returns true or false.' }
'list' { return 'List all projects. Returns an array of project objects.' }
else { return 'This is generic method for the root object, TODO fill in, ...' }
}
}
// API example method
pub fn (self Project) example(methodname string) (string, string) {
match methodname {
'set' {
return '{"project": {"name": "Website Redesign", "description": "Redesign company website", "status": "active", "owner_id": 1, "members": [2, 3]}}', '1'
}
'get' {
return '{"id": 1}', '{"name": "Website Redesign", "description": "Redesign company website", "status": "active", "owner_id": 1, "members": [2, 3]}'
}
'delete' {
return '{"id": 1}', 'true'
}
'exist' {
return '{"id": 1}', 'true'
}
'list' {
return '{}', '[{"name": "Website Redesign", "description": "Redesign company website", "status": "active", "owner_id": 1, "members": [2, 3]}]'
}
else {
return '{}', '{}'
}
}
}
// API handler function
pub fn project_handle(mut f ModelsFactory, rpcid int, servercontext map[string]string, userref UserRef, method string, params string) !Response {
match method {
'get' {
id := db.decode_u32(params)!
res := f.project.get(id)!
return new_response(rpcid, json.encode_pretty(res))
}
'set' {
mut args := db.decode_generic[ProjectArg](params)!
mut o := f.project.new(args)!
if args.id != 0 {
o.id = args.id
}
o = f.project.set(o)!
return new_response_int(rpcid, int(o.id))
}
'delete' {
id := db.decode_u32(params)!
deleted := f.project.delete(id)!
if deleted {
return new_response_true(rpcid)
} else {
return new_error(rpcid,
code: 404
message: 'Project with ID ${id} not found'
)
}
}
'exist' {
id := db.decode_u32(params)!
if f.project.exist(id)! {
return new_response_true(rpcid)
} else {
return new_response_false(rpcid)
}
}
'list' {
args := db.decode_generic[ProjectListArg](params)!
res := f.project.list(args)!
return new_response(rpcid, json.encode_pretty(res))
}
else {
return new_error(rpcid,
code: 32601
message: 'Method ${method} not found on project'
)
}
}
}
```
This complete guide should provide all the necessary information to create and maintain models in the HeroModels system following the established patterns and best practices.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,15 @@
# Instructions Archive (Legacy Prompts)
This directory contains **archived / legacy AI prompt material** for `herolib`.
- Files here may describe **older workflows** (e.g. previous documentation generation or model pipelines).
- They are kept for **historical reference** and to help understand how things evolved.
- They are **not** guaranteed to match the current `herolib` implementation.
## Usage Guidelines
- Do **not** use these files as the primary source for new features or refactors.
- When generating code or documentation, prefer:
1. Code and module docs under `lib/` (e.g. `lib/web/site/ai_instructions.md`, `lib/web/docusaurus/README.md`).
2. Up-to-date AI instructions under `aiprompts/` (outside of `instructions_archive/`).
- Only consult this directory when you explicitly need to understand **historical behavior** or migrate old flows.

View File

@@ -1,6 +1,6 @@
params:
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
@@ -18,8 +18,8 @@ the template is as follows
## factory
is there factory, which one and quick example how to call, dont say in which file not relevant
show how to import the module is as follows: import freeflowuniverse.herolib.
and then starting from lib e.g. lib/clients/mycelium would result in import freeflowuniverse.herolib. clients.mycelium
show how to import the module is as follows: import incubaid.herolib.
and then starting from lib e.g. lib/clients/mycelium would result in import incubaid.herolib. clients.mycelium
## overview
@@ -45,8 +45,8 @@ don't mention what we don't show because of rules above.
the only output we want is markdown file as follows
===WRITE===
===WRITE===
$filepath
===CONTENT===
$the content of the generated markdown file
===END===
===END===

View File

@@ -10,13 +10,11 @@ start of output file is:
## factory
is there factory, which one and quick example how to call, dont say in which file not relevant
show how to import the module is as follows: import freeflowuniverse.herolib.
and then starting from lib e.g. lib/clients/mycelium would result in import freeflowuniverse.herolib. clients.mycelium
show how to import the module is as follows: import incubaid.herolib.
and then starting from lib e.g. lib/clients/mycelium would result in import incubaid.herolib. clients.mycelium
## structs and methods
quick overview as list with identations, of the structs and its methods
ONLY OUTPUT THE MARKDOWN FILE, NOTHING ELSE

View File

@@ -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
@@ -17,16 +17,14 @@ don't do anything additional for modules, don't do import
at top of each file we have ```module $NAME```
make sure all time related fields are in u64 format, use unix timestamp for that
don't create management classes, only output the structs, don't create a mod.v, don't make .v scripts executatble, don't create a main.v
## now also make sure we use core.base as follows
```
import freeflowuniverse.herolib.hero.models.core
import incubaid.herolib.hero.models.core
// Account represents a financial account for tracking balances and transactions
// Supports multiple account types (checking, savings, investment, etc.)

View File

@@ -3,7 +3,7 @@ for governance and legal
make sure we use core.base as follows
import freeflowuniverse.herolib.hero.models.core
import incubaid.herolib.hero.models.core
// Account represents a financial account for tracking balances and transactions
// Supports multiple account types (checking, savings, investment, etc.)

View File

@@ -0,0 +1,109 @@
## INTENT
we use heroscript to communicate actions and events in a structured format.
we want you to parse user intents and generate the corresponding heroscript.
ONLY RETURN THE HEROSCRIPT STATEMENTS, can be more than 1
## HEROSCRIPT FORMAT
HeroScript is a concise scripting language with the following structure:
```heroscript
!!actor.action_name
param1: 'value1'
param2: 'value with spaces'
multiline_description: '
This is a multiline description.
It can span multiple lines.
'
arg1 arg2 // Arguments without keys
!!actor.action_name2 param1:something param2:'something with spaces' nr:3
```
Key characteristics:
- **Actions**: Start with `!!`, followed by `actor.action_name` (e.g., `!!mailclient.configure`).
- **Parameters**: Defined as `key:value`. Values can be quoted for spaces.
- **Multiline Support**: Parameters like `description` can span multiple lines.
- **Arguments**: Values without keys (e.g., `arg1`).
- params can be on 1 line, with spaces in between
- time can be as +1h, +1d, +1w (hour, day, week), ofcourse 1 can be any number, +1 means 1 hour from now
- time format is: dd/mm/yyyy hh:mm (ONLY USE THIS)
- comma separation is used a lot in arguments e.g. 'jan,kristof' or 'jan , kristof' remove spaces, is list of 2
- note only !! is at start of line, rest has spaces per instruction
- make one empty line between 1 heroscript statements
- everything after // is comment
## HEROSCRIPT SCHEMA
the language we understand
### calendar management
```heroscript
!!calendar.create when:'+1h' descr:'this is event to discuss eng' attendees:'jan,kristof' name:'meet1' tags:'eng,urgent'
!!calendar.delete name:'meet1'
!!calendar.list tags:'urgent'
```
### contact management
```heroscript
!!contact.add name:'jan' email:'jan@example.com' phone:'123-456-7890'
!!contact.remove name:'jan'
!!contact.list
```
### task management
```heroscript
!!task.create title:'Prepare presentation' due:'+1d' assignee:'jan' name:'task1' tags:'eng,urgent'
deadline:'+10d' duration:'1h'
!!task.update name:'task1' status:'in progress'
!!task.delete name:'task1'
!!task.list
```
### project management
```heroscript
!!project.create title:'Cloud Product Development' description:'Track progress of cloud product development' name:'cloud_prod'
!!project.update name:'cloud_prod' status:'in progress'
!!project.delete name:'cloud_prod'
!!project.list
!!project.tasks_list name:'cloud_prod' //required properties are name, description, and assignee of not given ask
!!project.tasks_add names:'task1, task2'
!!project.tasks_remove names:'task1, task2'
```
### SUPPORTED TAGS
only tags supported are:
- for intent: eng, prod, support, mgmt, marketing
- for urgency: urgent, high, medium, low
### generic remarks
- names are lowercase and snake_case, can be distilled out of title if only title given, often a user will say name but that means title
- time: format of returned data or time is always dd/mm/yyyy hh:min
## IMPORTANT STARTING INFO
- current time is 10/08/2025 05:10 , use this to define any time-related parameters
## USER INTENT
I want a meeting tomorrow 10am, where we will discuss our new product for the cloud with jan and alex, and the urgency is high
also let me know which other meetings I have which are urgent
can you make a project where we can track the progress of our new product development? Name is 'Cloud Product Development'
Please add tasks to the project in line to creating specifications, design documents, and implementation plans.

View File

@@ -0,0 +1,64 @@
SYSTEM
You are a HeroScript compiler. Convert user intents into valid HeroScript statements.
OUTPUT RULES
1) Return ONLY HeroScript statements. No prose, no backticks.
2) Separate each statement with exactly ONE blank line.
3) Keys use snake_case. Names are lowercase snake_case derived from titles (non-alnum → "_", collapse repeats, trim).
4) Lists are comma-separated with NO spaces (e.g., "jan,alex").
5) Times: OUTPUT MUST BE ABSOLUTE in "dd/mm/yyyy hh:mm" (Europe/Zurich). Convert relative times (e.g., "tomorrow 10am") using CURRENT_TIME.
6) Tags: include at most one intent tag and at most one urgency tag when present.
- intent: eng,prod,support,mgmt,marketing
- urgency: urgent,high,medium,low
7) Quotes: quote values containing spaces; otherwise omit quotes (allowed either way).
8) Comments only with // if the user explicitly asks for explanations; otherwise omit.
SCHEMA (exact actions & parameters)
!!calendar.create when:'dd/mm/yyyy hh:mm' name:'<name>' descr:'<text>' attendees:'a,b,c' tags:'intent,urgency'
!!calendar.delete name:'<name>'
!!calendar.list [tags:'tag1,tag2']
!!contact.add name:'<name>' email:'<email>' phone:'<phone>'
!!contact.remove name:'<name>'
!!contact.list
!!task.create title:'<title>' name:'<name>' [due:'dd/mm/yyyy hh:mm'] [assignee:'<name>'] [tags:'intent,urgency'] [deadline:'dd/mm/yyyy hh:mm'] [duration:'<Nd Nh Nm> or <Nh>']
!!task.update name:'<name>' [status:'in progress|done|blocked|todo']
!!task.delete name:'<name>'
!!task.list
!!project.create title:'<title>' description:'<text>' name:'<name>'
!!project.update name:'<name>' [status:'in progress|done|blocked|todo']
!!project.delete name:'<name>'
!!project.list
!!project.tasks_list name:'<project_name>'
!!project.tasks_add name:'<project_name>' names:'task_a,task_b'
!!project.tasks_remove name:'<project_name>' names:'task_a,task_b'
NORMALIZATION & INFERENCE (silent)
- Derive names from titles when missing (see rule 3). Ensure consistency across statements.
- Map phrases to tags when obvious (e.g., "new product" ⇒ intent: prod; "high priority" ⇒ urgency: high).
- Attendees: split on commas, trim, lowercase given names.
- If the user asks for “urgent meetings,” use tags:'urgent' specifically.
- Prefer concise descriptions pulled from the users phrasing.
- Name's are required, if missing ask for clarification.
- For calendar management, ensure to include all relevant details such as time, attendees, and description.
CURRENT_TIME
10/08/2025 05:10
USER_MESSAGE
I want a meeting tomorrow 10am, where we will discuss our new product for the cloud with jan and alex, and the urgency is high
also let me know which other meetings I have which are urgent
can you make a project where we can track the progress of our new product development? Name is 'Cloud Product Development'
Please add tasks to the project in line to creating specifications, design documents, and implementation plans.
END

View File

@@ -0,0 +1,82 @@
## INSTRUCTIONS
the user will send me multiple instructions what they wants to do, I want you to put them in separate categories
The categories we have defined are:
- calendar management
- schedule meetings, events, reminders
- list these events
- delete them
- contact management
- add/remove contact information e.g. phone numbers, email addresses, address information
- list contacts, search
- task or project management
- anything we need to do, anything we need to track and plan
- create/update tasks, set deadlines
- mark tasks as complete
- delete tasks
- project management
- communication (chat, email)
- see what needs to be communicate e.g. send a chat to ...
- search statements
- find on internet, find specific information from my friends
I want you to detect the intent and make multiple blocks out of the intent, each block should correspond to one of the identified intents, identify the intent with name of the category eg. calendar, only use above names
what user wants to do, stay as close as possible to the original instructions, copy the exact instructions as where given by the user, we only need to sort the instructions in these blocks
for each instruction make a separate block, e.g. if 2 tasks are given, create 2 blocks
the format to return is: (note newline after each title of block)
```template
===CALENDAR===\n
$the copied text from what user wants
===CONTACT===\n
...
===QUESTION===\n
put here what our system needs to ask to the user anything which is not clear
===END===\n
```
I want you to execute above on instructions as given by user below, give text back ONLY supporting the template
note for format is only ===$NAME=== and then on next lines the original instructions from the user, don't change
## special processing of info
- if a date or time specified e.g. tomorrow, time, ... calculate back from current date
## IMPORTANT STARTING INFO
- current time is 10/08/2025 05:10 (format of returned data is always dd/mm/yyyy hh:min)
- use the current time to define formatted time out of instructions
- only return the formatted time
## UNCLEAR INFO
check in instructions e.g. things specified like you, me, ...
are not clear ask specifically who do you mean
if task, specify per task, who needs to do it and when, make sure each instruction (block) is complete and clear for further processing
be very specific with the questions e.g. who is you, ...
## EXECUTE ABOVE ON THE FOLLOWING
I am planning a birthday for my daughters tomorrow, there will be 10 people.
I would like to know if you can help me with the preparations.
I need a place for my daughter's birthday party.
I need to send message to my wife isabelle that she needs to pick up the cake.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,371 @@
# Unpoly API Complete Reference & Operational Guide for AI Coding Agents
## Introduction
This document serves as a complete, self-contained reference manual for the **Unpoly JavaScript API**. It is written explicitly for AI coding agents that need to generate, validate, or refactor Unpoly-enhanced HTML and JavaScript code.
Unpoly is a front-end framework for progressive enhancement. It allows HTML pages to update fragments instead of reloading the full document, enabling seamless transitions, modals, caching, and navigation while maintaining server-side rendering.
An AI agent should use this manual to:
- Understand each Unpoly module and its purpose.
- Generate correct `up-*` attributes and JavaScript calls.
- Detect configuration errors and provide correction suggestions.
- Apply Unpoly in automated scaffolding, validation, and optimization workflows.
---
## 1. The up.link Module
### Purpose
Handles Unpoly-enhanced navigation. Converts normal links into AJAX-based fragment updates rather than full-page reloads.
### Core Concepts
When a user clicks a link with certain attributes, Unpoly intercepts the event and fetches the new page in the background. It then replaces specified fragments in the current document with matching elements from the response.
### Common Attributes
| Attribute | Description |
| --------------- | -------------------------------------------------------- |
| `up-follow` | Marks the link as handled by Unpoly. Usually implied. |
| `up-target` | CSS selector identifying which fragment(s) to replace. |
| `up-method` | Overrides HTTP method (e.g. `GET`, `POST`). |
| `up-params` | Adds query parameters to the request. |
| `up-headers` | Adds or overrides HTTP headers. |
| `up-layer` | Determines which layer (page, overlay, modal) to update. |
| `up-transition` | Defines animation during fragment replacement. |
| `up-cache` | Enables caching of the response. |
| `up-history` | Controls browser history behavior. |
### JavaScript API Methods
- `up.link.isFollowable(element)` Returns true if Unpoly will intercept the link.
- `up.link.follow(element, options)` Programmatically follow the link via Unpoly.
- `up.link.preload(element, options)` Preload the linked resource into the cache.
### Agent Reasoning & Validation
- Ensure that every `up-follow` element has a valid `up-target` selector.
- Validate that target elements exist in both the current DOM and the server response.
- Recommend `up-cache` for commonly visited links to improve performance.
- Prevent using `target="_blank"` or `download` attributes with Unpoly links.
### Example
```html
<a href="/profile" up-target="#main" up-transition="fade">View Profile</a>
```
---
## 2. The up.form Module
### Purpose
Handles progressive enhancement for forms. Submissions happen via AJAX and update only specific fragments.
### Core Attributes
| Attribute | Description |
| ---------------- | --------------------------------------- |
| `up-submit` | Marks form to be submitted via Unpoly. |
| `up-target` | Fragment selector to update on success. |
| `up-fail-target` | Selector to update if submission fails. |
| `up-validate` | Enables live field validation. |
| `up-autosubmit` | Submits automatically on change. |
| `up-disable-for` | Disables fields during request. |
| `up-enable-for` | Enables fields after request completes. |
### JavaScript API
- `up.form.submit(form, options)` Submit programmatically.
- `up.validate(field, options)` Trigger server validation.
- `up.form.fields(form)` Returns all input fields.
### Agent Reasoning
- Always ensure form has both `action` and `method` attributes.
- Match `up-target` to an element existing in the rendered HTML.
- For validation, ensure server supports `X-Up-Validate` header.
- When generating forms, add `up-fail-target` to handle errors gracefully.
### Example
```html
<form action="/update" method="POST" up-submit up-target="#user-info" up-fail-target="#form-errors">
<input name="email" up-validate required>
<button type="submit">Save</button>
</form>
```
---
## 3. The up.layer Module
### Purpose
Manages overlays, modals, and stacked layers of navigation.
### Attributes
| Attribute | Description |
| ---------------- | -------------------------------------------------- |
| `up-layer="new"` | Opens content in a new overlay. |
| `up-size` | Controls modal size (e.g., `small`, `large`). |
| `up-dismissable` | Allows overlay to close by clicking outside. |
| `up-history` | Determines if the overlay updates browser history. |
| `up-title` | Sets overlay title. |
### JavaScript API
- `up.layer.open(options)` Opens a new layer.
- `up.layer.close(layer)` Closes a given layer.
- `up.layer.on(event, callback)` Hooks into lifecycle events.
### Agent Notes
- Ensure `up-layer="new"` only used with valid targets.
- For overlays, set `up-history="false"` unless explicitly required.
- Auto-generate dismiss buttons with `up-layer-close`.
### Example
```html
<a href="/settings" up-layer="new" up-size="large" up-target=".modal-content">Open Settings</a>
```
---
## 4. The up.fragment Module
### Purpose
Handles low-level fragment rendering, preserving, replacing, and merging.
### JavaScript API
- `up.render(options)` Replace fragment(s) with new content.
- `up.fragment.config` Configure defaults for rendering.
- `up.fragment.get(target)` Retrieve a fragment.
### Example
```js
up.render({ target: '#main', url: '/dashboard', transition: 'fade' })
```
### Agent Notes
- Ensure only fragment HTML is sent from server (not full document).
- Use `preserve` for elements like forms where input state matters.
---
## 5. The up.network Module
### Purpose
Handles network requests, caching, and aborting background loads.
### JavaScript API
- `up.network.loadPage(url, options)` Load a page via Unpoly.
- `up.network.abort()` Abort ongoing requests.
- `up.network.config.timeout` Default timeout setting.
### Agent Tasks
- Preload probable links (`up.link.preload`).
- Use caching for frequent calls.
- Handle `up:network:late` event to show spinners.
---
## 6. The up.event Module
### Purpose
Manages custom events fired throughout Unpolys lifecycle.
### Common Events
- `up:link:follow`
- `up:form:submit`
- `up:layer:open`
- `up:layer:close`
- `up:rendered`
- `up:network:late`
### Example
```js
up.on('up:layer:close', (event) => {
console.log('Overlay closed');
});
```
### Agent Actions
- Register listeners for key events.
- Prevent duplicate bindings.
- Offer analytics hooks for `up:rendered` or `up:location:changed`.
---
## 7. The up.motion Module
Handles animations and transitions.
### API
- `up.motion()` Animate elements.
- `up.animate(element, keyframes, options)` Custom animation.
### Agent Notes
- Suggest `up-transition="fade"` or similar for fragment changes.
- Avoid heavy animations for performance-sensitive devices.
---
## 8. The up.radio Module
Handles broadcasting and receiving cross-fragment events.
### Example
```js
up.radio.emit('user:updated', { id: 5 })
up.radio.on('user:updated', (data) => console.log(data))
```
### Agent Tasks
- Use for coordinating multiple fragments.
- Ensure channel names are namespaced (e.g., `form:valid`, `modal:open`).
---
## 9. The up.history Module
### Purpose
Manages URL history, titles, and restoration.
### API
- `up.history.push(url, options)` Push new history entry.
- `up.history.restore()` Restore previous state.
### Agent Guidance
- Disable history (`up-history="false"`) for temporary overlays.
- Ensure proper title update via `up-title`.
---
## 10. The up.viewport Module
### Purpose
Manages scrolling, focusing, and viewport restoration.
### API
- `up.viewport.scroll(element)` Scroll to element.
- `up.viewport.restoreScroll()` Restore previous position.
### Agent Tasks
- Restore scroll after fragment updates.
- Manage focus for accessibility after `up.render()`.
---
## 11. The up.protocol Module
Handles request headers and special HTTP status codes.
### Key Concepts
- Adds `X-Up-Target` and `X-Up-Validate` headers.
- Interprets redirect and validation responses.
### Agent Notes
- Ensure backend supports Unpoly headers.
- Warn if 204 or redirect status used without fragments.
---
## 12. The up.util Module
Contains helpers for arrays, strings, and timing.
### Examples
```js
up.util.escapeHTML("<script>") // "&lt;script&gt;"
up.util.copy(text)
```
### Agent Tasks
- Use helpers for DOM-safe generation.
- Avoid reimplementing basic utilities.
---
## 13. The up.framework and up.log Modules
- `up.framework.init()` Initializes Unpoly.
- `up.log.enable()` Enables debug logging.
### Agent Tasks
- Always call `up.framework.init()` once.
- Enable logging during debug sessions.
---
Good addition — including **Unpoly from a CDN** is essential for setup and automation.
Heres the section you can append to the Markdown file (I can also regenerate the full file with it included if you prefer):
---
## 14. Including Unpoly from CDN
### Purpose
Before any Unpoly features or attributes (`up-*`) can work, the library must be loaded into the page.
For AI agents generating HTML pages or templates, always include Unpolys **CSS** and **JavaScript** assets early in the `<head>` section.
### Basic Setup (Latest Stable Version)
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My Unpoly Page</title>
<!-- Unpoly Core Styles -->
<link rel="stylesheet" href="https://unpkg.com/unpoly@3.7.2/unpoly.min.css">
<!-- Optional Bootstrap integration -->
<link rel="stylesheet" href="https://unpkg.com/unpoly@3.7.2/unpoly-bootstrap3.min.css">
<!-- Unpoly Core Script -->
<script src="https://unpkg.com/unpoly@3.7.2/unpoly.min.js"></script>
<!-- Initialize framework -->
<script>
up.framework.init()
</script>
</head>
<body>
<!-- Page content -->
</body>
</html>
```
### AI Agent Notes
* Always include **`unpoly.min.css`** before any custom styles to ensure default animations and transitions function properly.
* **Never** load Unpoly twice; check if the page already has a `<script src="...unpoly.min.js">`.
* After loading, the agent may immediately use Unpoly JavaScript APIs (`up.render`, `up.link.follow`, etc.) or rely on HTML attributes.
* If dynamically injecting HTML pages, the agent should re-run `up.framework.init()` **only once globally**, not after every fragment load.
### Recommended CDN Sources
* `https://unpkg.com/unpoly@3.x/`
* `https://cdn.jsdelivr.net/npm/unpoly@3.x/`
### Offline Use
For fully offline or embedded environments, the agent can download both `.js` and `.css` files and reference them locally:
```html
<link rel="stylesheet" href="/assets/unpoly.min.css">
<script src="/assets/unpoly.min.js"></script>
```
---
## Agent Validation Checklist
1. Verify `up-*` attributes match existing fragments.
2. Check backend returns valid fragment markup.
3. Ensure forms use `up-submit` and `up-fail-target`.
4. Overlay layers must have dismissable controls.
5. Use caching wisely (`up-cache`, `up.link.preload`).
6. Handle network and render events gracefully.
7. Log events (`up.log`) for debugging.
8. Confirm scroll/focus restoration after renders.
9. Gracefully degrade if JavaScript disabled.
10. Document reasoning and configuration.

View File

@@ -0,0 +1,647 @@
# Unpoly Quick Reference for AI Agents
## Installation
Include Unpoly from CDN in your HTML `<head>`:
```html
<script src="https://unpoly.com/unpoly.min.js"></script>
<link rel="stylesheet" href="https://unpoly.com/unpoly.min.css">
```
## Core Concept
Unpoly updates page fragments without full page reloads. Users click links/submit forms → server responds with HTML → Unpoly extracts and swaps matching fragments.
---
## 1. Following Links (Fragment Updates)
### Basic Link Following
```html
<a href="/users/5" up-follow>View User</a>
```
Updates the `<main>` element (or `<body>` if no main exists) with content from `/users/5`.
### Target Specific Fragment
```html
<a href="/users/5" up-target=".user-details">View User</a>
<div class="user-details">
<!-- Content replaced here -->
</div>
```
### Multiple Fragments
```html
<a href="/users/5" up-target=".profile, .activity">View User</a>
```
Updates both `.profile` and `.activity` from single response.
### Append/Prepend Content
```html
<!-- Append to list -->
<a href="/items?page=2" up-target=".items:after">Load More</a>
<!-- Prepend to list -->
<a href="/latest" up-target=".items:before">Show Latest</a>
```
### Handle All Links Automatically
```js
up.link.config.followSelectors.push('a[href]')
```
Now all links update fragments by default.
---
## 2. Submitting Forms
### Basic Form Submission
```html
<form action="/users" method="post" up-submit>
<input name="email">
<button type="submit">Create</button>
</form>
```
Submits via AJAX and updates `<main>` with response.
### Target Specific Fragment
```html
<form action="/search" up-submit up-target=".results">
<input name="query">
<button>Search</button>
</form>
<div class="results">
<!-- Search results appear here -->
</div>
```
### Handle Success vs. Error Responses
```html
<form action="/users" method="post" up-submit
up-target="#success"
up-fail-target="form">
<input name="email">
<button>Create</button>
</form>
<div id="success">Success message here</div>
```
- **Success (2xx status)**: Updates `#success`
- **Error (4xx/5xx status)**: Re-renders `form` with validation errors
**Server must return HTTP 422** (or similar error code) for validation failures.
---
## 3. Opening Overlays (Modal, Drawer, Popup)
### Modal Dialog
```html
<a href="/details" up-layer="new">Open Modal</a>
```
Opens `/details` in a modal overlay.
### Drawer (Sidebar)
```html
<a href="/menu" up-layer="new drawer">Open Drawer</a>
```
### Popup (Anchored to Link)
```html
<a href="/help" up-layer="new popup">Help</a>
```
### Close Overlay When Condition Met
```html
<a href="/users/new"
up-layer="new"
up-accept-location="/users/$id"
up-on-accepted="console.log('Created user:', value.id)">
New User
</a>
```
Overlay auto-closes when URL matches `/users/123`, passes `{ id: 123 }` to callback.
### Local Content (No Server Request)
```html
<a up-layer="new popup" up-content="<p>Help text here</p>">Help</a>
```
---
## 4. Validation
### Validate on Field Change
```html
<form action="/users" method="post">
<input name="email" up-validate>
<input name="password" up-validate>
<button type="submit">Register</button>
</form>
```
When field loses focus → submits form with `X-Up-Validate: email` header → server re-renders form → Unpoly updates the field's parent `<fieldset>` (or closest form group).
**Server must return HTTP 422** for validation errors.
### Validate While Typing
```html
<input name="email" up-validate
up-watch-event="input"
up-watch-delay="300">
```
Validates 300ms after user stops typing.
---
## 5. Lazy Loading & Polling
### Load When Element Appears in DOM
```html
<div id="menu" up-defer up-href="/menu">
Loading menu...
</div>
```
Immediately loads `/menu` when placeholder renders.
### Load When Scrolled Into View
```html
<div id="comments" up-defer="reveal" up-href="/comments">
Loading comments...
</div>
```
Loads when element scrolls into viewport.
### Auto-Refresh (Polling)
```html
<div class="status" up-poll up-interval="5000">
Current status
</div>
```
Reloads fragment every 5 seconds from original URL.
---
## 6. Caching & Revalidation
### Enable Caching
```html
<a href="/users" up-cache="true">Users</a>
```
Caches response, instantly shows cached content, then revalidates with server.
### Disable Caching
```html
<a href="/stock" up-cache="false">Live Prices</a>
```
### Conditional Requests (Server-Side)
Server sends:
```http
HTTP/1.1 200 OK
ETag: "abc123"
<div class="data">Content</div>
```
Next reload, Unpoly sends:
```http
GET /path
If-None-Match: "abc123"
```
Server responds `304 Not Modified` if unchanged → saves bandwidth.
---
## 7. Navigation Bar (Current Link Highlighting)
```html
<nav>
<a href="/home">Home</a>
<a href="/about">About</a>
</nav>
```
Current page link gets `.up-current` class automatically.
**Style it:**
```css
.up-current {
font-weight: bold;
color: blue;
}
```
---
## 8. Loading State
### Feedback Classes
Automatically applied:
- `.up-active` on clicked link/button
- `.up-loading` on targeted fragment
**Style them:**
```css
.up-active { opacity: 0.6; }
.up-loading { opacity: 0.8; }
```
### Disable Form While Submitting
```html
<form up-submit up-disable>
<input name="email">
<button>Submit</button>
</form>
```
All fields disabled during submission.
### Show Placeholder While Loading
```html
<a href="/data" up-target=".data"
up-placeholder="<p>Loading...</p>">
Load Data
</a>
```
---
## 9. Preloading
### Preload on Hover
```html
<a href="/users/5" up-preload>User Profile</a>
```
Starts loading when user hovers (90ms delay by default).
### Preload Immediately
```html
<a href="/menu" up-preload="insert">Menu</a>
```
Loads as soon as link appears in DOM.
---
## 10. Templates (Client-Side HTML)
### Define Template
```html
<template id="user-card">
<div class="card">
<h3>{{name}}</h3>
<p>{{email}}</p>
</div>
</template>
```
### Use Template
```html
<a up-fragment="#user-card"
up-use-data="{ name: 'Alice', email: 'alice@example.com' }">
Show User
</a>
```
**Process variables with compiler:**
```js
up.compiler('.card', function(element, data) {
element.innerHTML = element.innerHTML
.replace(/{{name}}/g, data.name)
.replace(/{{email}}/g, data.email)
})
```
---
## 11. JavaScript API
### Render Fragment
```js
up.render({
url: '/users/5',
target: '.user-details'
})
```
### Navigate (Updates History)
```js
up.navigate({
url: '/users',
target: 'main'
})
```
### Submit Form
```js
let form = document.querySelector('form')
up.submit(form)
```
### Open Overlay
```js
up.layer.open({
url: '/users/new',
onAccepted: (event) => {
console.log('User created:', event.value)
}
})
```
### Close Overlay with Value
```js
up.layer.accept({ id: 123, name: 'Alice' })
```
### Reload Fragment
```js
up.reload('.status')
```
---
## 12. Request Headers (Server Protocol)
Unpoly sends these headers with requests:
| Header | Value | Purpose |
| --------------- | -------- | ------------------------------- |
| `X-Up-Version` | `1.0.0` | Identifies Unpoly request |
| `X-Up-Target` | `.users` | Fragment selector being updated |
| `X-Up-Mode` | `modal` | Current layer mode |
| `X-Up-Validate` | `email` | Field being validated |
**Server can respond with:**
| Header | Effect |
| ------------------------ | ------------------------ |
| `X-Up-Target: .other` | Changes target selector |
| `X-Up-Accept-Layer: {}` | Closes overlay (success) |
| `X-Up-Dismiss-Layer: {}` | Closes overlay (cancel) |
---
## 13. Common Patterns
### Infinite Scrolling
```html
<div id="items">
<div>Item 1</div>
<div>Item 2</div>
</div>
<a id="next" href="/items?page=2"
up-defer="reveal"
up-target="#items:after, #next">
Load More
</a>
```
### Dependent Form Fields
```html
<form action="/order">
<!-- Changing country updates city select -->
<select name="country" up-validate="#city">
<option>USA</option>
<option>Canada</option>
</select>
<select name="city" id="city">
<option>New York</option>
</select>
</form>
```
### Confirm Before Action
```html
<a href="/delete" up-method="delete"
up-confirm="Really delete?">
Delete
</a>
```
### Auto-Submit on Change
```html
<form action="/search" up-autosubmit>
<input name="query">
</form>
```
Submits form when any field changes.
---
## 14. Error Handling
### Handle Network Errors
```js
up.on('up:fragment:offline', function(event) {
if (confirm('You are offline. Retry?')) {
event.retry()
}
})
```
### Handle Failed Responses
```js
try {
await up.render({ url: '/path', target: '.data' })
} catch (error) {
if (error instanceof up.RenderResult) {
console.log('Server error:', error)
}
}
```
---
## 15. Compilers (Enhance Elements)
### Basic Compiler
```js
up.compiler('.current-time', function(element) {
element.textContent = new Date().toString()
})
```
Runs when `.current-time` is inserted (initial load OR fragment update).
### Compiler with Cleanup
```js
up.compiler('.auto-refresh', function(element) {
let timer = setInterval(() => {
element.textContent = new Date().toString()
}, 1000)
// Return destructor function
return () => clearInterval(timer)
})
```
Destructor called when element is removed from DOM.
---
## Quick Reference Table
| Task | HTML | JavaScript |
| --------------- | ---------------------------- | -------------------------- |
| Follow link | `<a href="/path" up-follow>` | `up.follow(link)` |
| Submit form | `<form up-submit>` | `up.submit(form)` |
| Target fragment | `up-target=".foo"` | `{ target: '.foo' }` |
| Open modal | `up-layer="new"` | `up.layer.open({ url })` |
| Validate field | `up-validate` | `up.validate(field)` |
| Lazy load | `up-defer` | — |
| Poll fragment | `up-poll` | — |
| Preload link | `up-preload` | `up.link.preload(link)` |
| Local content | `up-content="<p>Hi</p>"` | `{ content: '<p>Hi</p>' }` |
| Append content | `up-target=".list:after"` | — |
| Confirm action | `up-confirm="Sure?"` | `{ confirm: 'Sure?' }` |
---
## Key Defaults
- **Target**: Updates `<main>` (or `<body>`) if no `up-target` specified
- **Caching**: Auto-enabled for GET requests during navigation
- **History**: Auto-updated when rendering `<main>` or major fragments
- **Scrolling**: Auto-scrolls to top when updating `<main>`
- **Focus**: Auto-focuses new fragment
- **Validation**: Targets field's parent `<fieldset>` or form group
---
## Best Practices for AI Agents
1. **Always provide HTTP error codes**: Return 422 for validation errors, 404 for not found, etc.
2. **Send full HTML responses**: Include entire page structure; Unpoly extracts needed fragments
3. **Use semantic HTML**: `<main>`, `<nav>`, `<form>` elements work best
4. **Set IDs on fragments**: Makes targeting easier (e.g., `<div id="user-123">`)
5. **Return consistent selectors**: If request targets `.users`, response must contain `.users`
---
## Common Mistakes to Avoid
**Don't**: Return only partial HTML without wrapper
```html
<h1>Title</h1>
<p>Content</p>
```
**Do**: Wrap in target selector
```html
<div class="content">
<h1>Title</h1>
<p>Content</p>
</div>
```
**Don't**: Return 200 OK for validation errors
**Do**: Return 422 Unprocessable Entity
**Don't**: Use `onclick="up.follow(this)"`
**Do**: Use `up-follow` attribute (handles keyboard, accessibility)
---
## Server Response Examples
### Successful Form Submission
```http
HTTP/1.1 200 OK
<div id="success">
User created successfully!
</div>
```
### Validation Error
```http
HTTP/1.1 422 Unprocessable Entity
<form action="/users" method="post" up-submit>
<input name="email" value="invalid">
<div class="error">Email is invalid</div>
<button>Submit</button>
</form>
```
### Partial Response (Optimized)
```http
HTTP/1.1 200 OK
Vary: X-Up-Target
<div class="user-details">
<!-- Only the targeted fragment -->
</div>
```

View File

@@ -0,0 +1,73 @@
## `crypto.blake3` Module
```v
fn sum256(data []u8) []u8
```
Returns the Blake3 256-bit hash of the provided data.
```v
fn sum_derive_key256(context []u8, key_material []u8) []u8
```
Computes the Blake3 256-bit derived-key hash based on the context and key material.
```v
fn sum_keyed256(data []u8, key []u8) []u8
```
Returns the Blake3 256-bit keyed hash of the data using the specified key.
---
### Digest-Based API
```v
fn Digest.new_derive_key_hash(context []u8) !Digest
```
Initializes a `Digest` struct for creating a Blake3 derivedkey hash, using the provided context.
```v
fn Digest.new_hash() !Digest
```
Initializes a `Digest` struct for a standard (unkeyed) Blake3 hash.
```v
fn Digest.new_keyed_hash(key []u8) !Digest
```
Initializes a `Digest` struct for a keyed Blake3 hash, with the given key.
---
### `Digest` Methods
```v
fn (mut d Digest) write(data []u8) !
```
Feeds additional data bytes into the ongoing hash computation.
```v
fn (mut d Digest) checksum(size u64) []u8
```
Finalizes the hash and returns the resulting output.
* The `size` parameter specifies the number of output bytes—commonly `32` for a 256-bit digest, but can be up to `2**64`.
---
### Recommended Usage (in V)
```v
import crypto.blake3
mut hasher := crypto.blake3.Digest.new_hash() or { panic(err) }
hasher.write(data) or { panic(err) }
digest := hasher.checksum(24) // returns a []u8 of length 24 (192 bits)
```

View File

@@ -1,26 +1,26 @@
module net
## Description
`net` provides networking functions. It is mostly a wrapper to BSD sockets, so you can listen on a port, connect to remote TCP/UDP services, and communicate with them.
const msg_nosignal = 0x4000
const err_connection_refused = error_with_code('net: connection refused', errors_base + 10)
const err_option_wrong_type = error_with_code('net: set_option_xxx option wrong type',
errors_base + 3)
errors_base + 3)
const opts_can_set = [
SocketOption.broadcast,
.debug,
.dont_route,
.keep_alive,
.linger,
.oob_inline,
.receive_buf_size,
.receive_low_size,
.receive_timeout,
.send_buf_size,
.send_low_size,
.send_timeout,
.ipv6_only,
SocketOption.broadcast,
.debug,
.dont_route,
.keep_alive,
.linger,
.oob_inline,
.receive_buf_size,
.receive_low_size,
.receive_timeout,
.send_buf_size,
.send_low_size,
.send_timeout,
.ipv6_only,
]
const error_eagain = C.EAGAIN
const err_port_out_of_range = error_with_code('net: port out of range', errors_base + 5)
@@ -29,12 +29,12 @@ const err_connect_failed = error_with_code('net: connect failed', errors_base +
const errors_base = 0
Well defined errors that are returned from socket functions
const opts_int = [
SocketOption.receive_buf_size,
.receive_low_size,
.receive_timeout,
.send_buf_size,
.send_low_size,
.send_timeout,
SocketOption.receive_buf_size,
.receive_low_size,
.receive_timeout,
.send_buf_size,
.send_low_size,
.send_timeout,
]
const error_eintr = C.EINTR
const error_ewouldblock = C.EWOULDBLOCK
@@ -43,17 +43,17 @@ const error_einprogress = C.EINPROGRESS
const err_timed_out_code = errors_base + 9
const err_connect_timed_out = error_with_code('net: connect timed out', errors_base + 8)
const err_new_socket_failed = error_with_code('net: new_socket failed to create socket',
errors_base + 1)
errors_base + 1)
const msg_dontwait = C.MSG_DONTWAIT
const infinite_timeout = time.infinite
infinite_timeout should be given to functions when an infinite_timeout is wanted (i.e. functions only ever return with data)
const no_timeout = time.Duration(0)
no_timeout should be given to functions when no timeout is wanted (i.e. all functions return instantly)
const err_timed_out = error_with_code('net: op timed out', errors_base + 9)
const tcp_default_read_timeout = 30 * time.second
const tcp_default_read_timeout = 30 *time.second
const err_option_not_settable = error_with_code('net: set_option_xxx option not settable',
errors_base + 2)
const tcp_default_write_timeout = 30 * time.second
errors_base + 2)
const tcp_default_write_timeout = 30* time.second
fn addr_from_socket_handle(handle int) Addr
addr_from_socket_handle returns an address, based on the given integer socket `handle`
fn close(handle int) !
@@ -94,16 +94,16 @@ fn validate_port(port int) !u16
validate_port checks whether a port is valid and returns the port or an error
fn wrap_error(error_code int) !
interface Connection {
addr() !Addr
peer_addr() !Addr
addr() !Addr
peer_addr() !Addr
mut:
read(mut []u8) !int
write([]u8) !int
close() !
read(mut []u8) !int
write([]u8) !int
close() !
}
Connection provides a generic SOCK_STREAM style interface that protocols can use as a base connection object to support TCP, UNIX Domain Sockets and various proxying solutions.
interface Dialer {
dial(address string) !Connection
dial(address string) !Connection
}
Dialer is an abstract dialer interface for producing connections to adresses.
fn (mut s TcpSocket) set_option_bool(opt SocketOption, value bool) !
@@ -114,49 +114,49 @@ fn (mut s TcpSocket) bind(addr string) !
fn (mut s UdpSocket) set_option_bool(opt SocketOption, value bool) !
fn (mut s UdpSocket) set_dualstack(on bool) !
enum AddrFamily {
unix = C.AF_UNIX
ip = C.AF_INET
ip6 = C.AF_INET6
unspec = C.AF_UNSPEC
unix = C.AF_UNIX
ip = C.AF_INET
ip6 = C.AF_INET6
unspec = C.AF_UNSPEC
}
AddrFamily are the available address families
enum ShutdownDirection {
read
write
read_and_write
read
write
read_and_write
}
ShutdownDirection is used by `net.shutdown`, for specifying the direction for which the communication will be cut.
enum SocketOption {
// TODO: SO_ACCEPT_CONN is not here because windows doesn't support it
// and there is no easy way to define it
broadcast = C.SO_BROADCAST
debug = C.SO_DEBUG
dont_route = C.SO_DONTROUTE
error = C.SO_ERROR
keep_alive = C.SO_KEEPALIVE
linger = C.SO_LINGER
oob_inline = C.SO_OOBINLINE
reuse_addr = C.SO_REUSEADDR
receive_buf_size = C.SO_RCVBUF
receive_low_size = C.SO_RCVLOWAT
receive_timeout = C.SO_RCVTIMEO
send_buf_size = C.SO_SNDBUF
send_low_size = C.SO_SNDLOWAT
send_timeout = C.SO_SNDTIMEO
socket_type = C.SO_TYPE
ipv6_only = C.IPV6_V6ONLY
// TODO: SO_ACCEPT_CONN is not here because windows doesn't support it
// and there is no easy way to define it
broadcast = C.SO_BROADCAST
debug = C.SO_DEBUG
dont_route = C.SO_DONTROUTE
error = C.SO_ERROR
keep_alive = C.SO_KEEPALIVE
linger = C.SO_LINGER
oob_inline = C.SO_OOBINLINE
reuse_addr = C.SO_REUSEADDR
receive_buf_size = C.SO_RCVBUF
receive_low_size = C.SO_RCVLOWAT
receive_timeout = C.SO_RCVTIMEO
send_buf_size = C.SO_SNDBUF
send_low_size = C.SO_SNDLOWAT
send_timeout = C.SO_SNDTIMEO
socket_type = C.SO_TYPE
ipv6_only = C.IPV6_V6ONLY
}
enum SocketType {
udp = C.SOCK_DGRAM
tcp = C.SOCK_STREAM
seqpacket = C.SOCK_SEQPACKET
udp = C.SOCK_DGRAM
tcp = C.SOCK_STREAM
seqpacket = C.SOCK_SEQPACKET
}
SocketType are the available sockets
struct Addr {
pub:
len u8
f u8
addr AddrData
len u8
f u8
addr AddrData
}
fn (a Addr) family() AddrFamily
family returns the family/kind of the given address `a`
@@ -168,72 +168,72 @@ fn (a Addr) str() string
str returns a string representation of the address `a`
struct C.addrinfo {
mut:
ai_family int
ai_socktype int
ai_flags int
ai_protocol int
ai_addrlen int
ai_addr voidptr
ai_canonname voidptr
ai_next voidptr
ai_family int
ai_socktype int
ai_flags int
ai_protocol int
ai_addrlen int
ai_addr voidptr
ai_canonname voidptr
ai_next voidptr
}
struct C.fd_set {}
struct C.sockaddr_in {
mut:
sin_len u8
sin_family u8
sin_port u16
sin_addr u32
sin_zero [8]char
sin_len u8
sin_family u8
sin_port u16
sin_addr u32
sin_zero [8]char
}
struct C.sockaddr_in6 {
mut:
// 1 + 1 + 2 + 4 + 16 + 4 = 28;
sin6_len u8 // 1
sin6_family u8 // 1
sin6_port u16 // 2
sin6_flowinfo u32 // 4
sin6_addr [16]u8 // 16
sin6_scope_id u32 // 4
// 1 + 1 + 2 + 4 + 16 + 4 = 28;
sin6_len u8 // 1
sin6_family u8 // 1
sin6_port u16 // 2
sin6_flowinfo u32 // 4
sin6_addr [16]u8 // 16
sin6_scope_id u32 // 4
}
struct C.sockaddr_un {
mut:
sun_len u8
sun_family u8
sun_path [max_unix_path]char
sun_len u8
sun_family u8
sun_path [max_unix_path]char
}
struct Ip {
port u16
addr [4]u8
// Pad to size so that socket functions
// dont complain to us (see in.h and bind())
// TODO(emily): I would really like to use
// some constant calculations here
// so that this doesnt have to be hardcoded
sin_pad [8]u8
port u16
addr [4]u8
// Pad to size so that socket functions
// dont complain to us (see in.h and bind())
// TODO(emily): I would really like to use
// some constant calculations here
// so that this doesnt have to be hardcoded
sin_pad [8]u8
}
fn (a Ip) str() string
str returns a string representation of `a`
struct Ip6 {
port u16
flow_info u32
addr [16]u8
scope_id u32
port u16
flow_info u32
addr [16]u8
scope_id u32
}
fn (a Ip6) str() string
str returns a string representation of `a`
struct ListenOptions {
pub:
dualstack bool = true
backlog int = 128
dualstack bool = true
backlog int = 128
}
struct ShutdownConfig {
pub:
how ShutdownDirection = .read_and_write
how ShutdownDirection = .read_and_write
}
struct Socket {
pub:
handle int
handle int
}
fn (s &Socket) address() !Addr
address gets the address of a socket
@@ -243,13 +243,13 @@ fn (t TCPDialer) dial(address string) !Connection
dial will try to create a new abstract connection to the given address. It will return an error, if that is not possible.
struct TcpConn {
pub mut:
sock TcpSocket
handle int
write_deadline time.Time
read_deadline time.Time
read_timeout time.Duration
write_timeout time.Duration
is_blocking bool = true
sock TcpSocket
handle int
write_deadline time.Time
read_deadline time.Time
read_timeout time.Duration
write_timeout time.Duration
is_blocking bool = true
}
fn (c &TcpConn) addr() !Addr
fn (mut c TcpConn) close() !
@@ -265,7 +265,7 @@ fn (c TcpConn) read(mut buf []u8) !int
fn (mut c TcpConn) read_deadline() !time.Time
fn (mut con TcpConn) read_line() string
read_line is a *simple*, *non customizable*, blocking line reader. It will return a line, ending with LF, or just '', on EOF.
Note: if you want more control over the buffer, please use a buffered IO reader instead: `io.new_buffered_reader({reader: io.make_reader(con)})`
fn (mut con TcpConn) read_line_max(max_line_len int) string
read_line_max is a *simple*, *non customizable*, blocking line reader. It will return a line, ending with LF, '' on EOF. It stops reading, when the result line length exceeds max_line_len.
@@ -278,7 +278,7 @@ fn (mut c TcpConn) set_read_deadline(deadline time.Time)
fn (mut c TcpConn) set_read_timeout(t time.Duration)
fn (mut c TcpConn) set_sock() !
set_sock initialises the c.sock field. It should be called after `.accept_only()!`.
Note: just use `.accept()!`. In most cases it is simpler, and calls `.set_sock()!` for you.
fn (mut c TcpConn) set_write_deadline(deadline time.Time)
fn (mut c TcpConn) set_write_timeout(t time.Duration)
@@ -295,19 +295,17 @@ fn (mut c TcpConn) write_string(s string) !int
fn (c &TcpConn) write_timeout() time.Duration
struct TcpListener {
pub mut:
sock TcpSocket
accept_timeout time.Duration
accept_deadline time.Time
is_blocking bool = true
sock TcpSocket
accept_timeout time.Duration
accept_deadline time.Time
is_blocking bool = true
}
fn (mut l TcpListener) accept() !&TcpConn
accept a tcp connection from an external source to the listener `l`.
fn (mut l TcpListener) accept_only() !&TcpConn
accept_only accepts a tcp connection from an external source to the listener `l`. Unlike `accept`, `accept_only` *will not call* `.set_sock()!` on the result, and is thus faster.
Note: you *need* to call `.set_sock()!` manually, before using theconnection after calling `.accept_only()!`, but that does not have to happen in the same thread that called `.accept_only()!`. The intention of this API, is to have a more efficient way to accept connections, that are later processed by a thread pool, while the main thread remains active, so that it can accept other connections. See also vlib/vweb/vweb.v .
Note: you *need* to call `.set_sock()!` manually, before using theconnection after calling `.accept_only()!`, but that does not have to happen in the same thread that called `.accept_only()!`. The intention of this API, is to have a more efficient way to accept connections, that are later processed by a thread pool, while the main thread remains active, so that it can accept other connections. See also vlib/veb/veb.v .
If you do not need that, just call `.accept()!` instead, which will call `.set_sock()!` for you.
fn (c &TcpListener) accept_deadline() !time.Time
@@ -319,12 +317,12 @@ fn (mut c TcpListener) close() !
fn (c &TcpListener) addr() !Addr
struct UdpConn {
pub mut:
sock UdpSocket
sock UdpSocket
mut:
write_deadline time.Time
read_deadline time.Time
read_timeout time.Duration
write_timeout time.Duration
write_deadline time.Time
read_deadline time.Time
read_timeout time.Duration
write_timeout time.Duration
}
fn (mut c UdpConn) write_ptr(b &u8, len int) !int
sock := UdpSocket{ handle: sbase.handle l: local r: resolve_wrapper(raddr) } }
@@ -350,5 +348,5 @@ fn (mut c UdpConn) wait_for_write() !
fn (c &UdpConn) str() string
fn (mut c UdpConn) close() !
struct Unix {
path [max_unix_path]char
path [max_unix_path]char
}

View File

@@ -83,7 +83,7 @@ fn main() {
}
```
```vlang
```v
module time

View File

@@ -0,0 +1,785 @@
# module arrays
## Contents
- [append](#append)
- [binary_search](#binary_search)
- [carray_to_varray](#carray_to_varray)
- [chunk](#chunk)
- [chunk_while](#chunk_while)
- [concat](#concat)
- [copy](#copy)
- [distinct](#distinct)
- [each](#each)
- [each_indexed](#each_indexed)
- [filter_indexed](#filter_indexed)
- [find_first](#find_first)
- [find_last](#find_last)
- [flat_map](#flat_map)
- [flat_map_indexed](#flat_map_indexed)
- [flatten](#flatten)
- [fold](#fold)
- [fold_indexed](#fold_indexed)
- [group](#group)
- [group_by](#group_by)
- [idx_max](#idx_max)
- [idx_min](#idx_min)
- [index_of_first](#index_of_first)
- [index_of_last](#index_of_last)
- [join_to_string](#join_to_string)
- [lower_bound](#lower_bound)
- [map_indexed](#map_indexed)
- [map_of_counts](#map_of_counts)
- [map_of_indexes](#map_of_indexes)
- [max](#max)
- [merge](#merge)
- [min](#min)
- [partition](#partition)
- [reduce](#reduce)
- [reduce_indexed](#reduce_indexed)
- [reverse_iterator](#reverse_iterator)
- [rotate_left](#rotate_left)
- [rotate_right](#rotate_right)
- [sum](#sum)
- [uniq](#uniq)
- [uniq_all_repeated](#uniq_all_repeated)
- [uniq_only](#uniq_only)
- [uniq_only_repeated](#uniq_only_repeated)
- [upper_bound](#upper_bound)
- [window](#window)
- [ReverseIterator[T]](#ReverseIterator[T])
- [next](#next)
- [free](#free)
- [ReverseIterator](#ReverseIterator)
- [WindowAttribute](#WindowAttribute)
## append
```v
fn append[T](a []T, b []T) []T
```
append the second array `b` to the first array `a`, and return the result. Note, that unlike arrays.concat, arrays.append is less flexible, but more efficient, since it does not require you to use ...a for the second parameter.
Example
```v
arrays.append([1, 3, 5, 7], [2, 4, 6, 8]) // => [1, 3, 5, 7, 2, 4, 6, 8]
```
[[Return to contents]](#Contents)
## binary_search
```v
fn binary_search[T](array []T, target T) !int
```
binary_search, requires `array` to be sorted, returns index of found item or error. Binary searches on sorted lists can be faster than other array searches because at maximum the algorithm only has to traverse log N elements
Example
```v
arrays.binary_search([1, 2, 3, 4], 4)! // => 3
```
[[Return to contents]](#Contents)
## carray_to_varray
```v
fn carray_to_varray[T](c_array_data voidptr, items int) []T
```
carray_to_varray copies a C byte array into a V array of type `T`. See also: `cstring_to_vstring`
[[Return to contents]](#Contents)
## chunk
```v
fn chunk[T](array []T, size int) [][]T
```
chunk array into a single array of arrays where each element is the next `size` elements of the original.
Example
```v
arrays.chunk([1, 2, 3, 4, 5, 6, 7, 8, 9], 2) // => [[1, 2], [3, 4], [5, 6], [7, 8], [9]]
```
[[Return to contents]](#Contents)
## chunk_while
```v
fn chunk_while[T](a []T, predicate fn (before T, after T) bool) [][]T
```
chunk_while splits the input array `a` into chunks of varying length, using the `predicate`, passing to it pairs of adjacent elements `before` and `after`. Each chunk, will contain all ajdacent elements, for which the `predicate` returned true. The chunks are split *between* the `before` and `after` elements, for which the `predicate` returned false.
Examples
```v
assert arrays.chunk_while([0,9,2,2,3,2,7,5,9,5],fn(x int,y int)bool{return x<=y})==[[0,9],[2,2,3],[2,7],[5,9],[5]]
assert arrays.chunk_while('aaaabbbcca'.runes(),fn(x rune,y rune)bool{return x==y})==[[`a`,`a`,`a`,`a`],[`b`,`b`,`b`],[`c`,`c`],[`a`]]
assert arrays.chunk_while('aaaabbbcca'.runes(),fn(x rune,y rune)bool{return x==y}).map({it[0]:it.len})==[{`a`:4},{`b`:3},{`c`:2},{`a`:1}]
```
[[Return to contents]](#Contents)
## concat
```v
fn concat[T](a []T, b ...T) []T
```
concatenate an array with an arbitrary number of additional values.
Note: if you have two arrays, you should simply use the `<<` operator directly.
Examples
```v
assert arrays.concat([1, 2, 3], 4, 5, 6) == [1, 2, 3, 4, 5, 6]
assert arrays.concat([1, 2, 3], ...[4, 5, 6]) == [1, 2, 3, 4, 5, 6]
mut arr := arrays.concat([1, 2, 3], 4); arr << [10,20]; assert arr == [1,2,3,4,10,20] // note: arr is mutable
```
[[Return to contents]](#Contents)
## copy
```v
fn copy[T](mut dst []T, src []T) int
```
copy copies the `src` array elements to the `dst` array. The number of the elements copied is the minimum of the length of both arrays. Returns the number of elements copied.
[[Return to contents]](#Contents)
## distinct
```v
fn distinct[T](a []T) []T
```
distinct returns all distinct elements from the given array a. The results are guaranteed to be unique, i.e. not have duplicates. See also arrays.uniq, which can be used to achieve the same goal, but needs you to first sort the array.
Example
```v
assert arrays.distinct( [5, 5, 1, 5, 2, 1, 1, 9] ) == [1, 2, 5, 9]
```
[[Return to contents]](#Contents)
## each
```v
fn each[T](a []T, cb fn (elem T))
```
each calls the callback fn `cb`, for each element of the given array `a`.
[[Return to contents]](#Contents)
## each_indexed
```v
fn each_indexed[T](a []T, cb fn (i int, e T))
```
each_indexed calls the callback fn `cb`, for each element of the given array `a`. It passes the callback both the index of the current element, and the element itself.
[[Return to contents]](#Contents)
## filter_indexed
```v
fn filter_indexed[T](array []T, predicate fn (idx int, elem T) bool) []T
```
filter_indexed filters elements based on `predicate` function being invoked on each element with its index in the original array.
[[Return to contents]](#Contents)
## find_first
```v
fn find_first[T](array []T, predicate fn (elem T) bool) ?T
```
find_first returns the first element that matches the given predicate. Returns `none` if no match is found.
Example
```v
arrays.find_first([1, 2, 3, 4, 5], fn (i int) bool { return i == 3 })? // => 3
```
[[Return to contents]](#Contents)
## find_last
```v
fn find_last[T](array []T, predicate fn (elem T) bool) ?T
```
find_last returns the last element that matches the given predicate. Returns `none` if no match is found.
Example
```v
arrays.find_last([1, 2, 3, 4, 5], fn (i int) bool { return i == 3})? // => 3
```
[[Return to contents]](#Contents)
## flat_map
```v
fn flat_map[T, R](array []T, transform fn (elem T) []R) []R
```
flat_map creates a new array populated with the flattened result of calling transform function being invoked on each element of `list`.
[[Return to contents]](#Contents)
## flat_map_indexed
```v
fn flat_map_indexed[T, R](array []T, transform fn (idx int, elem T) []R) []R
```
flat_map_indexed creates a new array with the flattened result of calling the `transform` fn, invoked on each idx,elem pair from the original.
[[Return to contents]](#Contents)
## flatten
```v
fn flatten[T](array [][]T) []T
```
flatten flattens n + 1 dimensional array into n dimensional array.
Example
```v
arrays.flatten[int]([[1, 2, 3], [4, 5]]) // => [1, 2, 3, 4, 5]
```
[[Return to contents]](#Contents)
## fold
```v
fn fold[T, R](array []T, init R, fold_op fn (acc R, elem T) R) R
```
fold sets `acc = init`, then successively calls `acc = fold_op(acc, elem)` for each element in `array`. returns `acc`.
Example
```v
// Sum the length of each string in an array
a := ['Hi', 'all']
r := arrays.fold[string, int](a, 0,
fn (r int, t string) int { return r + t.len })
assert r == 5
```
[[Return to contents]](#Contents)
## fold_indexed
```v
fn fold_indexed[T, R](array []T, init R, fold_op fn (idx int, acc R, elem T) R) R
```
fold_indexed sets `acc = init`, then successively calls `acc = fold_op(idx, acc, elem)` for each element in `array`. returns `acc`.
[[Return to contents]](#Contents)
## group
```v
fn group[T](arrs ...[]T) [][]T
```
group n arrays into a single array of arrays with n elements. This function is analogous to the "zip" function of other languages. To fully interleave two arrays, follow this function with a call to `flatten`.
Note: An error will be generated if the type annotation is omitted.
Example
```v
arrays.group[int]([1, 2, 3], [4, 5, 6]) // => [[1, 4], [2, 5], [3, 6]]
```
[[Return to contents]](#Contents)
## group_by
```v
fn group_by[K, V](array []V, grouping_op fn (val V) K) map[K][]V
```
group_by groups together elements, for which the `grouping_op` callback produced the same result.
Example
```v
arrays.group_by[int, string](['H', 'el', 'lo'], fn (v string) int { return v.len }) // => {1: ['H'], 2: ['el', 'lo']}
```
[[Return to contents]](#Contents)
## idx_max
```v
fn idx_max[T](array []T) !int
```
idx_max returns the index of the maximum value in the array.
Example
```v
arrays.idx_max([1, 2, 3, 0, 9])! // => 4
```
[[Return to contents]](#Contents)
## idx_min
```v
fn idx_min[T](array []T) !int
```
idx_min returns the index of the minimum value in the array.
Example
```v
arrays.idx_min([1, 2, 3, 0, 9])! // => 3
```
[[Return to contents]](#Contents)
## index_of_first
```v
fn index_of_first[T](array []T, predicate fn (idx int, elem T) bool) int
```
index_of_first returns the index of the first element of `array`, for which the predicate fn returns true. If predicate does not return true for any of the elements, then index_of_first will return -1.
Example
```v
assert arrays.index_of_first([4,5,0,7,0,9], fn(idx int, x int) bool { return x == 0 }) == 2
```
[[Return to contents]](#Contents)
## index_of_last
```v
fn index_of_last[T](array []T, predicate fn (idx int, elem T) bool) int
```
index_of_last returns the index of the last element of `array`, for which the predicate fn returns true. If predicate does not return true for any of the elements, then index_of_last will return -1.
Example
```v
assert arrays.index_of_last([4,5,0,7,0,9], fn(idx int, x int) bool { return x == 0 }) == 4
```
[[Return to contents]](#Contents)
## join_to_string
```v
fn join_to_string[T](array []T, separator string, transform fn (elem T) string) string
```
join_to_string takes in a custom transform function and joins all elements into a string with the specified separator
[[Return to contents]](#Contents)
## lower_bound
```v
fn lower_bound[T](array []T, val T) !T
```
returns the smallest element >= val, requires `array` to be sorted.
Example
```v
arrays.lower_bound([2, 4, 6, 8], 3)! // => 4
```
[[Return to contents]](#Contents)
## map_indexed
```v
fn map_indexed[T, R](array []T, transform fn (idx int, elem T) R) []R
```
map_indexed creates a new array with the result of calling the `transform` fn, invoked on each idx,elem pair from the original.
[[Return to contents]](#Contents)
## map_of_counts
```v
fn map_of_counts[T](array []T) map[T]int
```
map_of_counts returns a map, where each key is an unique value in `array`. Each value in that map for that key, is how many times that value occurs in `array`. It can be useful for building histograms of discrete measurements.
Example
```v
assert arrays.map_of_counts([1,2,3,4,4,2,1,4,4]) == {1: 2, 2: 2, 3: 1, 4: 4}
```
[[Return to contents]](#Contents)
## map_of_indexes
```v
fn map_of_indexes[T](array []T) map[T][]int
```
map_of_indexes returns a map, where each key is an unique value in `array`. Each value in that map for that key, is an array, containing the indexes in `array`, where that value has been found.
Example
```v
assert arrays.map_of_indexes([1,2,3,4,4,2,1,4,4,999]) == {1: [0, 6], 2: [1, 5], 3: [2], 4: [3, 4, 7, 8], 999: [9]}
```
[[Return to contents]](#Contents)
## max
```v
fn max[T](array []T) !T
```
max returns the maximum value in the array.
Example
```v
arrays.max([1, 2, 3, 0, 9])! // => 9
```
[[Return to contents]](#Contents)
## merge
```v
fn merge[T](a []T, b []T) []T
```
merge two sorted arrays (ascending) and maintain sorted order.
Example
```v
arrays.merge([1, 3, 5, 7], [2, 4, 6, 8]) // => [1, 2, 3, 4, 5, 6, 7, 8]
```
[[Return to contents]](#Contents)
## min
```v
fn min[T](array []T) !T
```
min returns the minimum value in the array.
Example
```v
arrays.min([1, 2, 3, 0, 9])! // => 0
```
[[Return to contents]](#Contents)
## partition
```v
fn partition[T](array []T, predicate fn (elem T) bool) ([]T, []T)
```
partition splits the original array into pair of lists. The first list contains elements for which the predicate fn returned true, while the second list contains elements for which the predicate fn returned false.
[[Return to contents]](#Contents)
## reduce
```v
fn reduce[T](array []T, reduce_op fn (acc T, elem T) T) !T
```
reduce sets `acc = array[0]`, then successively calls `acc = reduce_op(acc, elem)` for each remaining element in `array`. returns the accumulated value in `acc`. returns an error if the array is empty. See also: [fold](#fold).
Example
```v
arrays.reduce([1, 2, 3, 4, 5], fn (t1 int, t2 int) int { return t1 * t2 })! // => 120
```
[[Return to contents]](#Contents)
## reduce_indexed
```v
fn reduce_indexed[T](array []T, reduce_op fn (idx int, acc T, elem T) T) !T
```
reduce_indexed sets `acc = array[0]`, then successively calls `acc = reduce_op(idx, acc, elem)` for each remaining element in `array`. returns the accumulated value in `acc`. returns an error if the array is empty. See also: [fold_indexed](#fold_indexed).
[[Return to contents]](#Contents)
## reverse_iterator
```v
fn reverse_iterator[T](a []T) ReverseIterator[T]
```
reverse_iterator can be used to iterate over the elements in an array. i.e. you can use this syntax: `for elem in arrays.reverse_iterator(a) {` .
[[Return to contents]](#Contents)
## rotate_left
```v
fn rotate_left[T](mut array []T, mid int)
```
rotate_left rotates the array in-place. It does it in such a way, that the first `mid` elements of the array, move to the end, while the last `array.len - mid` elements move to the front. After calling `rotate_left`, the element previously at index `mid` will become the first element in the array.
Example
```v
mut x := [1,2,3,4,5,6]
arrays.rotate_left(mut x, 2)
println(x) // [3, 4, 5, 6, 1, 2]
```
[[Return to contents]](#Contents)
## rotate_right
```v
fn rotate_right[T](mut array []T, k int)
```
rotate_right rotates the array in-place. It does it in such a way, that the first `array.len - k` elements of the array, move to the end, while the last `k` elements move to the front. After calling `rotate_right`, the element previously at index `array.len - k` will become the first element in the array.
Example
```v
mut x := [1,2,3,4,5,6]
arrays.rotate_right(mut x, 2)
println(x) // [5, 6, 1, 2, 3, 4]
```
[[Return to contents]](#Contents)
## sum
```v
fn sum[T](array []T) !T
```
sum up array, return an error, when the array has no elements.
Example
```v
arrays.sum([1, 2, 3, 4, 5])! // => 15
```
[[Return to contents]](#Contents)
## uniq
```v
fn uniq[T](a []T) []T
```
uniq filters the adjacent matching elements from the given array. All adjacent matching elements, are merged to their first occurrence, so the output will have no repeating elements.
Note: `uniq` does not detect repeats, unless they are adjacent. You may want to call a.sorted() on your array, before passing the result to arrays.uniq(). See also arrays.distinct, which is essentially arrays.uniq(a.sorted()) .
Examples
```v
assert arrays.uniq( []int{} ) == []
assert arrays.uniq( [1, 1] ) == [1]
assert arrays.uniq( [2, 1] ) == [2, 1]
assert arrays.uniq( [5, 5, 1, 5, 2, 1, 1, 9] ) == [5, 1, 5, 2, 1, 9]
```
[[Return to contents]](#Contents)
## uniq_all_repeated
```v
fn uniq_all_repeated[T](a []T) []T
```
uniq_all_repeated produces all adjacent matching elements from the given array. Unique elements, with no duplicates are removed. The output will contain all the duplicated elements, repeated just like they were in the original.
Note: `uniq_all_repeated` does not detect repeats, unless they are adjacent. You may want to call a.sorted() on your array, before passing the result to arrays.uniq_all_repeated().
Examples
```v
assert arrays.uniq_all_repeated( []int{} ) == []
assert arrays.uniq_all_repeated( [1, 5] ) == []
assert arrays.uniq_all_repeated( [5, 5] ) == [5,5]
assert arrays.uniq_all_repeated( [5, 5, 1, 5, 2, 1, 1, 9] ) == [5, 5, 1, 1]
```
[[Return to contents]](#Contents)
## uniq_only
```v
fn uniq_only[T](a []T) []T
```
uniq_only filters the adjacent matching elements from the given array. All adjacent matching elements, are removed. The output will contain only the elements that *did not have* any adjacent matches.
Note: `uniq_only` does not detect repeats, unless they are adjacent. You may want to call a.sorted() on your array, before passing the result to arrays.uniq_only().
Examples
```v
assert arrays.uniq_only( []int{} ) == []
assert arrays.uniq_only( [1, 1] ) == []
assert arrays.uniq_only( [2, 1] ) == [2, 1]
assert arrays.uniq_only( [1, 5, 5, 1, 5, 2, 1, 1, 9] ) == [1, 1, 5, 2, 9]
```
[[Return to contents]](#Contents)
## uniq_only_repeated
```v
fn uniq_only_repeated[T](a []T) []T
```
uniq_only_repeated produces the adjacent matching elements from the given array. Unique elements, with no duplicates are removed. Adjacent matching elements, are reduced to just 1 element per repeat group.
Note: `uniq_only_repeated` does not detect repeats, unless they are adjacent. You may want to call a.sorted() on your array, before passing the result to arrays.uniq_only_repeated().
Examples
```v
assert arrays.uniq_only_repeated( []int{} ) == []
assert arrays.uniq_only_repeated( [1, 5] ) == []
assert arrays.uniq_only_repeated( [5, 5] ) == [5]
assert arrays.uniq_only_repeated( [5, 5, 1, 5, 2, 1, 1, 9] ) == [5, 1]
```
[[Return to contents]](#Contents)
## upper_bound
```v
fn upper_bound[T](array []T, val T) !T
```
returns the largest element <= val, requires `array` to be sorted.
Example
```v
arrays.upper_bound([2, 4, 6, 8], 3)! // => 2
```
[[Return to contents]](#Contents)
## window
```v
fn window[T](array []T, attr WindowAttribute) [][]T
```
get snapshots of the window of the given size sliding along array with the given step, where each snapshot is an array.- `size` - snapshot size
- `step` - gap size between each snapshot, default is 1.
Examples
```v
arrays.window([1, 2, 3, 4], size: 2) // => [[1, 2], [2, 3], [3, 4]]
arrays.window([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], size: 3, step: 2) // => [[1, 2, 3], [3, 4, 5], [5, 6, 7], [7, 8, 9]]
```
[[Return to contents]](#Contents)
## ReverseIterator[T]
## next
```v
fn (mut iter ReverseIterator[T]) next() ?&T
```
next is the required method, to implement an iterator in V. It returns none when the iteration should stop. Otherwise it returns the current element of the array.
[[Return to contents]](#Contents)
## free
```v
fn (iter &ReverseIterator[T]) free()
```
free frees the iterator resources.
[[Return to contents]](#Contents)
## ReverseIterator
```v
struct ReverseIterator[T] {
mut:
a []T
i int
}
```
ReverseIterator provides a convenient way to iterate in reverse over all elements of an array without allocations. I.e. it allows you to use this syntax: `for elem in arrays.reverse_iterator(a) {` .
[[Return to contents]](#Contents)
## WindowAttribute
```v
struct WindowAttribute {
pub:
size int
step int = 1
}
```
[[Return to contents]](#Contents)
#### Powered by vdoc. Generated on: 2 Sep 2025 07:19:06

View File

@@ -0,0 +1,76 @@
# module diff
## Contents
- [diff](#diff)
- [DiffContext[T]](#DiffContext[T])
- [generate_patch](#generate_patch)
- [DiffChange](#DiffChange)
- [DiffContext](#DiffContext)
- [DiffGenStrParam](#DiffGenStrParam)
## diff
```v
fn diff[T](a []T, b []T) &DiffContext[T]
```
diff returns the difference of two arrays.
[[Return to contents]](#Contents)
## DiffContext[T]
## generate_patch
```v
fn (mut c DiffContext[T]) generate_patch(param DiffGenStrParam) string
```
generate_patch generate a diff string of two arrays.
[[Return to contents]](#Contents)
## DiffChange
```v
struct DiffChange {
pub mut:
a int // position in input a []T
b int // position in input b []T
del int // delete Del elements from input a
ins int // insert Ins elements from input b
}
```
DiffChange contains one or more deletions or inserts at one position in two arrays.
[[Return to contents]](#Contents)
## DiffContext
```v
struct DiffContext[T] {
mut:
a []T
b []T
flags []DiffContextFlag
max int
// forward and reverse d-path endpoint x components
forward []int
reverse []int
pub mut:
changes []DiffChange
}
```
[[Return to contents]](#Contents)
## DiffGenStrParam
```v
struct DiffGenStrParam {
pub mut:
colorful bool
unified int = 3 // how many context lines before/after diff block
block_header bool // output `@@ -3,4 +3,5 @@` or not
}
```
[[Return to contents]](#Contents)
#### Powered by vdoc. Generated on: 2 Sep 2025 07:19:06

View File

@@ -0,0 +1,53 @@
# module parallel
## Contents
- [amap](#amap)
- [run](#run)
- [Params](#Params)
## amap
```v
fn amap[T, R](input []T, worker fn (T) R, opt Params) []R
```
amap lets the user run an array of input with a user provided function in parallel. It limits the number of worker threads to max number of cpus. The worker function can return a value. The returning array maintains the input order. Any error handling should have happened within the worker function.
Example
```v
squares := parallel.amap([1, 2, 3, 4, 5], |i| i * i); assert squares == [1, 4, 9, 16, 25]
```
[[Return to contents]](#Contents)
## run
```v
fn run[T](input []T, worker fn (T), opt Params)
```
run lets the user run an array of input with a user provided function in parallel. It limits the number of worker threads to min(num_workers, num_cpu). The function aborts if an error is encountered.
Example
```v
parallel.run([1, 2, 3, 4, 5], |i| println(i))
```
[[Return to contents]](#Contents)
## Params
```v
struct Params {
pub mut:
workers int // 0 by default, so that VJOBS will be used, through runtime.nr_jobs()
}
```
Params contains the optional parameters that can be passed to `run` and `amap`.
[[Return to contents]](#Contents)
#### Powered by vdoc. Generated on: 2 Sep 2025 07:19:06

View File

@@ -0,0 +1,321 @@
# module benchmark
## Contents
- [Constants](#Constants)
- [new_benchmark](#new_benchmark)
- [new_benchmark_no_cstep](#new_benchmark_no_cstep)
- [new_benchmark_pointer](#new_benchmark_pointer)
- [start](#start)
- [Benchmark](#Benchmark)
- [set_total_expected_steps](#set_total_expected_steps)
- [stop](#stop)
- [step](#step)
- [step_restart](#step_restart)
- [fail](#fail)
- [ok](#ok)
- [skip](#skip)
- [fail_many](#fail_many)
- [ok_many](#ok_many)
- [neither_fail_nor_ok](#neither_fail_nor_ok)
- [measure](#measure)
- [record_measure](#record_measure)
- [step_message_with_label_and_duration](#step_message_with_label_and_duration)
- [step_message_with_label](#step_message_with_label)
- [step_message](#step_message)
- [step_message_ok](#step_message_ok)
- [step_message_fail](#step_message_fail)
- [step_message_skip](#step_message_skip)
- [total_message](#total_message)
- [all_recorded_measures](#all_recorded_measures)
- [total_duration](#total_duration)
- [MessageOptions](#MessageOptions)
## Constants
```v
const b_ok = term.ok_message('OK ')
```
[[Return to contents]](#Contents)
```v
const b_fail = term.fail_message('FAIL')
```
[[Return to contents]](#Contents)
```v
const b_skip = term.warn_message('SKIP')
```
[[Return to contents]](#Contents)
```v
const b_spent = term.ok_message('SPENT')
```
[[Return to contents]](#Contents)
## new_benchmark
```v
fn new_benchmark() Benchmark
```
new_benchmark returns a `Benchmark` instance on the stack.
[[Return to contents]](#Contents)
## new_benchmark_no_cstep
```v
fn new_benchmark_no_cstep() Benchmark
```
new_benchmark_no_cstep returns a new `Benchmark` instance with step counting disabled.
[[Return to contents]](#Contents)
## new_benchmark_pointer
```v
fn new_benchmark_pointer() &Benchmark
```
new_benchmark_pointer returns a new `Benchmark` instance allocated on the heap. This is useful for long-lived use of `Benchmark` instances.
[[Return to contents]](#Contents)
## start
```v
fn start() Benchmark
```
start returns a new, running, instance of `Benchmark`. This is a shorthand for calling `new_benchmark().step()`.
[[Return to contents]](#Contents)
## Benchmark
```v
struct Benchmark {
pub mut:
bench_timer time.StopWatch
verbose bool
no_cstep bool
step_timer time.StopWatch
ntotal int
nok int
nfail int
nskip int
nexpected_steps int
njobs int
cstep int
bok string
bfail string
measured_steps []string
step_data map[string][]f64
}
```
[[Return to contents]](#Contents)
## set_total_expected_steps
```v
fn (mut b Benchmark) set_total_expected_steps(n int)
```
set_total_expected_steps sets the total amount of steps the benchmark is expected to take.
[[Return to contents]](#Contents)
## stop
```v
fn (mut b Benchmark) stop()
```
stop stops the internal benchmark timer.
[[Return to contents]](#Contents)
## step
```v
fn (mut b Benchmark) step()
```
step increases the step count by 1 and restarts the internal timer.
[[Return to contents]](#Contents)
## step_restart
```v
fn (mut b Benchmark) step_restart()
```
step_restart will restart the internal step timer. Note that the step count will *stay the same*. This method is useful, when you want to do some optional preparation after you have called .step(), so that the time for that optional preparation will *not* be added to the duration of the step.
[[Return to contents]](#Contents)
## fail
```v
fn (mut b Benchmark) fail()
```
fail increases the fail count by 1 and stops the internal timer.
[[Return to contents]](#Contents)
## ok
```v
fn (mut b Benchmark) ok()
```
ok increases the ok count by 1 and stops the internal timer.
[[Return to contents]](#Contents)
## skip
```v
fn (mut b Benchmark) skip()
```
skip increases the skip count by 1 and stops the internal timer.
[[Return to contents]](#Contents)
## fail_many
```v
fn (mut b Benchmark) fail_many(n int)
```
fail_many increases the fail count by `n` and stops the internal timer.
[[Return to contents]](#Contents)
## ok_many
```v
fn (mut b Benchmark) ok_many(n int)
```
ok_many increases the ok count by `n` and stops the internal timer.
[[Return to contents]](#Contents)
## neither_fail_nor_ok
```v
fn (mut b Benchmark) neither_fail_nor_ok()
```
neither_fail_nor_ok stops the internal timer.
[[Return to contents]](#Contents)
## measure
```v
fn (mut b Benchmark) measure(label string) i64
```
measure prints the current time spent doing `label`, since the benchmark was started, or since its last call.
[[Return to contents]](#Contents)
## record_measure
```v
fn (mut b Benchmark) record_measure(label string) i64
```
record_measure stores the current time doing `label`, since the benchmark was started, or since the last call to `b.record_measure`. It is similar to `b.measure`, but unlike it, will not print the measurement immediately, just record it for later. You can call `b.all_recorded_measures` to retrieve all measures stored by `b.record_measure` calls.
[[Return to contents]](#Contents)
## step_message_with_label_and_duration
```v
fn (b &Benchmark) step_message_with_label_and_duration(label string, msg string, sduration time.Duration,
opts MessageOptions) string
```
step_message_with_label_and_duration returns a string describing the current step.
[[Return to contents]](#Contents)
## step_message_with_label
```v
fn (b &Benchmark) step_message_with_label(label string, msg string, opts MessageOptions) string
```
step_message_with_label returns a string describing the current step using current time as duration.
[[Return to contents]](#Contents)
## step_message
```v
fn (b &Benchmark) step_message(msg string, opts MessageOptions) string
```
step_message returns a string describing the current step.
[[Return to contents]](#Contents)
## step_message_ok
```v
fn (b &Benchmark) step_message_ok(msg string, opts MessageOptions) string
```
step_message_ok returns a string describing the current step with an standard "OK" label.
[[Return to contents]](#Contents)
## step_message_fail
```v
fn (b &Benchmark) step_message_fail(msg string, opts MessageOptions) string
```
step_message_fail returns a string describing the current step with an standard "FAIL" label.
[[Return to contents]](#Contents)
## step_message_skip
```v
fn (b &Benchmark) step_message_skip(msg string, opts MessageOptions) string
```
step_message_skip returns a string describing the current step with an standard "SKIP" label.
[[Return to contents]](#Contents)
## total_message
```v
fn (b &Benchmark) total_message(msg string) string
```
total_message returns a string with total summary of the benchmark run.
[[Return to contents]](#Contents)
## all_recorded_measures
```v
fn (b &Benchmark) all_recorded_measures() string
```
all_recorded_measures returns a string, that contains all the recorded measure messages, done by individual calls to `b.record_measure`.
[[Return to contents]](#Contents)
## total_duration
```v
fn (b &Benchmark) total_duration() i64
```
total_duration returns the duration in ms.
[[Return to contents]](#Contents)
## MessageOptions
```v
struct MessageOptions {
pub:
preparation time.Duration // the duration of the preparation time for the step
}
```
MessageOptions allows passing an optional preparation time too to each label method. If it is set, the preparation time (compile time) will be shown before the measured runtime.
[[Return to contents]](#Contents)
#### Powered by vdoc. Generated on: 2 Sep 2025 07:21:08

View File

@@ -0,0 +1,22 @@
# module builtin.linux_bare.old..checks.forkedtest
## Contents
- [normal_run](#normal_run)
- [run](#run)
## normal_run
```v
fn normal_run(op fn (), label string) int
```
[[Return to contents]](#Contents)
## run
```v
fn run(op fn (), label string, code Wi_si_code, status int) int
```
[[Return to contents]](#Contents)
#### Powered by vdoc. Generated on: 2 Sep 2025 07:18:39

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,220 @@
# module closure
## Contents
- [Constants](#Constants)
- [C.pthread_mutex_t](#C.pthread_mutex_t)
## Constants
```v
const closure_thunk = $if amd64 {
[
u8(0xF3),
0x44,
0x0F,
0x7E,
0x3D,
0xF7,
0xBF,
0xFF,
0xFF, // movq xmm15, QWORD PTR [rip - userdata]
0xFF,
0x25,
0xF9,
0xBF,
0xFF,
0xFF, // jmp QWORD PTR [rip - fn]
]
} $else $if i386 {
[
u8(0xe8),
0x00,
0x00,
0x00,
0x00, // call here
// here:
0x59, // pop ecx
0x66,
0x0F,
0x6E,
0xF9, // movd xmm7, ecx
0xff,
0xA1,
0xff,
0xbf,
0xff,
0xff, // jmp DWORD PTR [ecx - 0x4001] # <fn>
]
} $else $if arm64 {
[
u8(0x11),
0x00,
0xFE,
0x5C, // ldr d17, userdata
0x30,
0x00,
0xFE,
0x58, // ldr x16, fn
0x00,
0x02,
0x1F,
0xD6, // br x16
]
} $else $if arm32 {
[
u8(0x04),
0xC0,
0x4F,
0xE2, // adr ip, here
// here:
0x01,
0xC9,
0x4C,
0xE2, // sub ip, ip, #0x4000
0x90,
0xCA,
0x07,
0xEE, // vmov s15, ip
0x00,
0xC0,
0x9C,
0xE5, // ldr ip, [ip, 0]
0x1C,
0xFF,
0x2F,
0xE1, // bx ip
]
} $else $if rv64 {
[
u8(0x97),
0xCF,
0xFF,
0xFF, // auipc t6, 0xffffc
0x03,
0xBF,
0x8F,
0x00, // ld t5, 8(t6)
0x07,
0xB3,
0x0F,
0x00, // fld ft6, 0(t6)
0x67,
0x00,
0x0F,
0x00, // jr t5
]
} $else $if rv32 {
[
u8(0x97),
0xCF,
0xFF,
0xFF, // auipc t6, 0xffffc
0x03,
0xAF,
0x4F,
0x00, // lw t5, 4(t6)
0x07,
0xAB,
0x0F,
0x00, // flw fs6, 0(t6)
0x67,
0x00,
0x0F,
0x00, // jr t5
]
} $else $if s390x {
[
u8(0xC0),
0x70,
0xFF,
0xFF,
0xE0,
0x00, // larl %r7, -16384
0x68,
0xF0,
0x70,
0x00, // ld %f15, 0(%r7)
0xE3,
0x70,
0x70,
0x08,
0x00,
0x04, // lg %r7, 8(%r7)
0x07,
0xF7, // br %r7
]
} $else $if ppc64le {
[
u8(0xa6),
0x02,
0x08,
0x7c, // mflr %r0
0x05,
0x00,
0x00,
0x48, // bl here
0xa6,
0x02,
0xc8,
0x7d, // here: mflr %r14
0xf8,
0xbf,
0xce,
0x39, // addi %r14, %r14, -16392
0x00,
0x00,
0xce,
0xc9, // lfd %f14, 0(%r14)
0x08,
0x00,
0xce,
0xe9, // ld %r14, 8(%r14)
0xa6,
0x03,
0x08,
0x7c, // mtlr %r0
0xa6,
0x03,
0xc9,
0x7d, // mtctr %r14
0x20,
0x04,
0x80,
0x4e, // bctr
]
} $else $if loongarch64 {
[
u8(0x92),
0xFF,
0xFF,
0x1D, // pcaddu12i t6, -4
0x48,
0x02,
0x80,
0x2B, // fld.d f8, t6, 0
0x51,
0x22,
0xC0,
0x28, // ld.d t5, t6, 8
0x20,
0x02,
0x00,
0x4C, // jr t5
]
} $else {
[]u8{}
}
```
refer to https://godbolt.org/z/r7P3EYv6c for a complete assembly vfmt off
[[Return to contents]](#Contents)
## C.pthread_mutex_t
```v
struct C.pthread_mutex_t {}
```
[[Return to contents]](#Contents)
#### Powered by vdoc. Generated on: 2 Sep 2025 07:18:39

View File

@@ -0,0 +1,135 @@
# module wchar
## Contents
- [Constants](#Constants)
- [from_rune](#from_rune)
- [from_string](#from_string)
- [length_in_bytes](#length_in_bytes)
- [length_in_characters](#length_in_characters)
- [to_string](#to_string)
- [to_string2](#to_string2)
- [Character](#Character)
- [str](#str)
- [==](#==)
- [to_rune](#to_rune)
- [C.wchar_t](#C.wchar_t)
## Constants
```v
const zero = from_rune(0)
```
zero is a Character, that in C L"" strings represents the string end character (terminator).
[[Return to contents]](#Contents)
## from_rune
```v
fn from_rune(r rune) Character
```
from_rune creates a Character, given a V rune
[[Return to contents]](#Contents)
## from_string
```v
fn from_string(s string) &Character
```
from_string converts the V string (in UTF-8 encoding), into a newly allocated platform specific buffer of C.wchar_t . The conversion is done by processing each rune of the input string 1 by 1.
[[Return to contents]](#Contents)
## length_in_bytes
```v
fn length_in_bytes(p voidptr) int
```
length_in_bytes returns the length of the given wchar_t* wide C style L"" string in bytes. Note that the size of wchar_t is different on the different platforms, thus the length in bytes for the same data converted from UTF-8 to a &Character buffer, will be different as well. i.e. unsafe { wchar.length_in_bytes(wchar.from_string('abc')) } will be 12 on unix, but 6 on windows.
[[Return to contents]](#Contents)
## length_in_characters
```v
fn length_in_characters(p voidptr) int
```
See also `length_in_bytes` .
Example
```v
assert unsafe { wchar.length_in_characters(wchar.from_string('abc')) } == 3
```
[[Return to contents]](#Contents)
## to_string
```v
fn to_string(p voidptr) string
```
to_string creates a V string, encoded in UTF-8, given a wchar_t* wide C style L"" string. It relies that the string has a 0 terminator at its end, to determine the string's length. Note, that the size of wchar_t is platform-dependent, and is *2 bytes* on windows, while it is *4 bytes* on most everything else. Unless you are interfacing with a C library, that does specifically use `wchar_t`, consider using `string_from_wide` instead, which will always assume that the input data is in an UTF-16 encoding, no matter what the platform is.
[[Return to contents]](#Contents)
## to_string2
```v
fn to_string2(p voidptr, len int) string
```
to_string2 creates a V string, encoded in UTF-8, given a `C.wchar_t*` wide C style L"" string. Note, that the size of `C.wchar_t` is platform-dependent, and is *2 bytes* on windows, while *4* on most everything else. Unless you are interfacing with a C library, that does specifically use wchar_t, consider using string_from_wide2 instead, which will always assume that the input data is in an UTF-16 encoding, no matter what the platform is.
[[Return to contents]](#Contents)
## Character
```v
type Character = C.wchar_t
```
Character is a type, that eases working with the platform dependent C.wchar_t type.
Note: the size of C.wchar_t varies between platforms, it is 2 bytes on windows, and usually 4 bytes elsewhere.
[[Return to contents]](#Contents)
## str
```v
fn (a Character) str() string
```
return a string representation of the given Character
[[Return to contents]](#Contents)
## ==
```v
fn (a Character) == (b Character) bool
```
== is an equality operator, to ease comparing Characters
Todo: the default == operator, that V generates, does not work for C.wchar_t .
[[Return to contents]](#Contents)
## to_rune
```v
fn (c Character) to_rune() rune
```
to_rune creates a V rune, given a Character
[[Return to contents]](#Contents)
## C.wchar_t
```v
struct C.wchar_t {}
```
[[Return to contents]](#Contents)
#### Powered by vdoc. Generated on: 2 Sep 2025 07:18:39

View File

@@ -0,0 +1,80 @@
# module aes
## Contents
- [Constants](#Constants)
- [new_cipher](#new_cipher)
- [AesCipher](#AesCipher)
- [free](#free)
- [block_size](#block_size)
- [encrypt](#encrypt)
- [decrypt](#decrypt)
## Constants
```v
const block_size = 16
```
The AES block size in bytes.
[[Return to contents]](#Contents)
## new_cipher
```v
fn new_cipher(key []u8) cipher.Block
```
new_cipher creates and returns a new [[AesCipher](#AesCipher)]. The key argument should be the AES key, either 16, 24, or 32 bytes to select AES-128, AES-192, or AES-256.
[[Return to contents]](#Contents)
## AesCipher
## free
```v
fn (mut c AesCipher) free()
```
free the resources taken by the AesCipher `c`
[[Return to contents]](#Contents)
## block_size
```v
fn (c &AesCipher) block_size() int
```
block_size returns the block size of the checksum in bytes.
[[Return to contents]](#Contents)
## encrypt
```v
fn (c &AesCipher) encrypt(mut dst []u8, src []u8)
```
encrypt encrypts the first block of data in `src` to `dst`.
Note: `dst` and `src` are both mutable for performance reasons.
Note: `dst` and `src` must both be pre-allocated to the correct length.
Note: `dst` and `src` may be the same (overlapping entirely).
[[Return to contents]](#Contents)
## decrypt
```v
fn (c &AesCipher) decrypt(mut dst []u8, src []u8)
```
decrypt decrypts the first block of data in `src` to `dst`.
Note: `dst` and `src` are both mutable for performance reasons.
Note: `dst` and `src` must both be pre-allocated to the correct length.
Note: `dst` and `src` may be the same (overlapping entirely).
[[Return to contents]](#Contents)
#### Powered by vdoc. Generated on: 2 Sep 2025 07:18:17

View File

@@ -0,0 +1,123 @@
# module bcrypt
## Contents
- [Constants](#Constants)
- [compare_hash_and_password](#compare_hash_and_password)
- [generate_from_password](#generate_from_password)
- [generate_salt](#generate_salt)
- [Hashed](#Hashed)
- [free](#free)
## Constants
```v
const min_cost = 4
```
[[Return to contents]](#Contents)
```v
const max_cost = 31
```
[[Return to contents]](#Contents)
```v
const default_cost = 10
```
[[Return to contents]](#Contents)
```v
const salt_length = 16
```
[[Return to contents]](#Contents)
```v
const max_crypted_hash_size = 23
```
[[Return to contents]](#Contents)
```v
const encoded_salt_size = 22
```
[[Return to contents]](#Contents)
```v
const encoded_hash_size = 31
```
[[Return to contents]](#Contents)
```v
const min_hash_size = 59
```
[[Return to contents]](#Contents)
```v
const major_version = '2'
```
[[Return to contents]](#Contents)
```v
const minor_version = 'a'
```
[[Return to contents]](#Contents)
## compare_hash_and_password
```v
fn compare_hash_and_password(password []u8, hashed_password []u8) !
```
compare_hash_and_password compares a bcrypt hashed password with its possible hashed version.
[[Return to contents]](#Contents)
## generate_from_password
```v
fn generate_from_password(password []u8, cost int) !string
```
generate_from_password return a bcrypt string from Hashed struct.
[[Return to contents]](#Contents)
## generate_salt
```v
fn generate_salt() string
```
generate_salt generate a string to be treated as a salt.
[[Return to contents]](#Contents)
## Hashed
```v
struct Hashed {
mut:
hash []u8
salt []u8
cost int
major string
minor string
}
```
[[Return to contents]](#Contents)
## free
```v
fn (mut h Hashed) free()
```
free the resources taken by the Hashed `h`
[[Return to contents]](#Contents)
#### Powered by vdoc. Generated on: 2 Sep 2025 07:18:17

View File

@@ -0,0 +1,254 @@
# module blake2b
## Contents
- [Constants](#Constants)
- [new160](#new160)
- [new256](#new256)
- [new384](#new384)
- [new512](#new512)
- [new_digest](#new_digest)
- [new_pmac160](#new_pmac160)
- [new_pmac256](#new_pmac256)
- [new_pmac384](#new_pmac384)
- [new_pmac512](#new_pmac512)
- [pmac160](#pmac160)
- [pmac256](#pmac256)
- [pmac384](#pmac384)
- [pmac512](#pmac512)
- [sum160](#sum160)
- [sum256](#sum256)
- [sum384](#sum384)
- [sum512](#sum512)
- [Digest](#Digest)
- [str](#str)
- [write](#write)
- [checksum](#checksum)
## Constants
```v
const size160 = 20
```
size160 is the size, in bytes, of a Blake2b 160 checksum.
[[Return to contents]](#Contents)
```v
const size256 = 32
```
size256 is the size, in bytes, of a Blake2b 256 checksum.
[[Return to contents]](#Contents)
```v
const size384 = 48
```
size384 is the size, in bytes, of a Blake2b 384 checksum.
[[Return to contents]](#Contents)
```v
const size512 = 64
```
size512 is the size, in bytes, of a Blake2b 512 checksum.
[[Return to contents]](#Contents)
```v
const block_size = 128
```
block_size is the block size, in bytes, of the Blake2b hash functions.
[[Return to contents]](#Contents)
## new160
```v
fn new160() !&Digest
```
new160 initializes the digest structure for a Blake2b 160 bit hash
[[Return to contents]](#Contents)
## new256
```v
fn new256() !&Digest
```
new256 initializes the digest structure for a Blake2b 256 bit hash
[[Return to contents]](#Contents)
## new384
```v
fn new384() !&Digest
```
new384 initializes the digest structure for a Blake2b 384 bit hash
[[Return to contents]](#Contents)
## new512
```v
fn new512() !&Digest
```
new512 initializes the digest structure for a Blake2b 512 bit hash
[[Return to contents]](#Contents)
## new_digest
```v
fn new_digest(hash_size u8, key []u8) !&Digest
```
new_digest creates an initialized digest structure based on the hash size and whether or not you specify a MAC key.
hash_size - the number of bytes in the generated hash. Legal values are between 1 and 64.
key - key used for generating a prefix MAC. A zero length key is used for just generating a hash. A key of 1 to 64 bytes can be used for generating a prefix MAC.
[[Return to contents]](#Contents)
## new_pmac160
```v
fn new_pmac160(key []u8) !&Digest
```
new_pmac160 initializes the digest structure for a Blake2b 160 bit prefix MAC
[[Return to contents]](#Contents)
## new_pmac256
```v
fn new_pmac256(key []u8) !&Digest
```
new_pmac256 initializes the digest structure for a Blake2b 256 bit prefix MAC
[[Return to contents]](#Contents)
## new_pmac384
```v
fn new_pmac384(key []u8) !&Digest
```
new_pmac384 initializes the digest structure for a Blake2b 384 bit prefix MAC
[[Return to contents]](#Contents)
## new_pmac512
```v
fn new_pmac512(key []u8) !&Digest
```
new_pmac512 initializes the digest structure for a Blake2b 512 bit prefix MAC
[[Return to contents]](#Contents)
## pmac160
```v
fn pmac160(data []u8, key []u8) []u8
```
pmac160 returns the Blake2b 160 bit prefix MAC of the data.
[[Return to contents]](#Contents)
## pmac256
```v
fn pmac256(data []u8, key []u8) []u8
```
pmac256 returns the Blake2b 256 bit prefix MAC of the data.
[[Return to contents]](#Contents)
## pmac384
```v
fn pmac384(data []u8, key []u8) []u8
```
pmac384 returns the Blake2b 384 bit prefix MAC of the data.
[[Return to contents]](#Contents)
## pmac512
```v
fn pmac512(data []u8, key []u8) []u8
```
pmac512 returns the Blake2b 512 bit prefix MAC of the data.
[[Return to contents]](#Contents)
## sum160
```v
fn sum160(data []u8) []u8
```
sum160 returns the Blake2b 160 bit checksum of the data.
[[Return to contents]](#Contents)
## sum256
```v
fn sum256(data []u8) []u8
```
sum256 returns the Blake2b 256 bit checksum of the data.
[[Return to contents]](#Contents)
## sum384
```v
fn sum384(data []u8) []u8
```
sum384 returns the Blake2b 384 bit checksum of the data.
[[Return to contents]](#Contents)
## sum512
```v
fn sum512(data []u8) []u8
```
sum512 returns the Blake2b 512 bit checksum of the data.
[[Return to contents]](#Contents)
## Digest
## str
```v
fn (d Digest) str() string
```
string makes a formatted string representation of a Digest structure
[[Return to contents]](#Contents)
## write
```v
fn (mut d Digest) write(data []u8) !
```
write adds bytes to the hash
[[Return to contents]](#Contents)
## checksum
```v
fn (mut d Digest) checksum() []u8
```
checksum finalizes the hash and returns the generated bytes.
[[Return to contents]](#Contents)
#### Powered by vdoc. Generated on: 2 Sep 2025 07:18:17

View File

@@ -0,0 +1,254 @@
# module blake2s
## Contents
- [Constants](#Constants)
- [new128](#new128)
- [new160](#new160)
- [new224](#new224)
- [new256](#new256)
- [new_digest](#new_digest)
- [new_pmac128](#new_pmac128)
- [new_pmac160](#new_pmac160)
- [new_pmac224](#new_pmac224)
- [new_pmac256](#new_pmac256)
- [pmac128](#pmac128)
- [pmac160](#pmac160)
- [pmac224](#pmac224)
- [pmac256](#pmac256)
- [sum128](#sum128)
- [sum160](#sum160)
- [sum224](#sum224)
- [sum256](#sum256)
- [Digest](#Digest)
- [str](#str)
- [write](#write)
- [checksum](#checksum)
## Constants
```v
const size128 = 16
```
size128 is the size, in bytes, of a Blake2s 128 checksum.
[[Return to contents]](#Contents)
```v
const size160 = 20
```
size160 is the size, in bytes, of a Blake2s 160 checksum.
[[Return to contents]](#Contents)
```v
const size224 = 28
```
size224 is the size, in bytes, of a Blake2s 224 checksum.
[[Return to contents]](#Contents)
```v
const size256 = 32
```
size256 is the size, in bytes, of a Blake2s 256 checksum.
[[Return to contents]](#Contents)
```v
const block_size = 64
```
block_size is the block size, in bytes, of the Blake2s hash functions.
[[Return to contents]](#Contents)
## new128
```v
fn new128() !&Digest
```
new126 initializes the digest structure for a Blake2s 128 bit hash
[[Return to contents]](#Contents)
## new160
```v
fn new160() !&Digest
```
new160 initializes the digest structure for a Blake2s 160 bit hash
[[Return to contents]](#Contents)
## new224
```v
fn new224() !&Digest
```
new224 initializes the digest structure for a Blake2s 224 bit hash
[[Return to contents]](#Contents)
## new256
```v
fn new256() !&Digest
```
new256 initializes the digest structure for a Blake2s 256 bit hash
[[Return to contents]](#Contents)
## new_digest
```v
fn new_digest(hash_size u8, key []u8) !&Digest
```
new_digest creates an initialized digest structure based on the hash size and whether or not you specify a MAC key.
hash_size - the number of bytes in the generated hash. Legal values are between 1 and 32.
key - key used for generating a prefix MAC. A zero length key is used for just generating a hash. A key of 1 to 32 bytes can be used for generating a prefix MAC.
[[Return to contents]](#Contents)
## new_pmac128
```v
fn new_pmac128(key []u8) !&Digest
```
new_pmac128 initializes the digest structure for a Blake2s 128 bit prefix MAC
[[Return to contents]](#Contents)
## new_pmac160
```v
fn new_pmac160(key []u8) !&Digest
```
new_pmac160 initializes the digest structure for a Blake2s 160 bit prefix MAC
[[Return to contents]](#Contents)
## new_pmac224
```v
fn new_pmac224(key []u8) !&Digest
```
new_pmac224 initializes the digest structure for a Blake2s 224 bit prefix MAC
[[Return to contents]](#Contents)
## new_pmac256
```v
fn new_pmac256(key []u8) !&Digest
```
new_pmac256 initializes the digest structure for a Blake2s 256 bit prefix MAC
[[Return to contents]](#Contents)
## pmac128
```v
fn pmac128(data []u8, key []u8) []u8
```
pmac128 returns the Blake2s 128 bit prefix MAC of the data.
[[Return to contents]](#Contents)
## pmac160
```v
fn pmac160(data []u8, key []u8) []u8
```
pmac160 returns the Blake2s 160 bit prefix MAC of the data.
[[Return to contents]](#Contents)
## pmac224
```v
fn pmac224(data []u8, key []u8) []u8
```
pmac224 returns the Blake2s 224 bit prefix MAC of the data.
[[Return to contents]](#Contents)
## pmac256
```v
fn pmac256(data []u8, key []u8) []u8
```
pmac256 returns the Blake2s 256 bit prefix MAC of the data.
[[Return to contents]](#Contents)
## sum128
```v
fn sum128(data []u8) []u8
```
sum128 returns the Blake2s 128 bit checksum of the data.
[[Return to contents]](#Contents)
## sum160
```v
fn sum160(data []u8) []u8
```
sum160 returns the Blake2s 160 bit checksum of the data.
[[Return to contents]](#Contents)
## sum224
```v
fn sum224(data []u8) []u8
```
sum224 returns the Blake2s 224 bit checksum of the data.
[[Return to contents]](#Contents)
## sum256
```v
fn sum256(data []u8) []u8
```
sum256 returns the Blake2s 256 bit checksum of the data.
[[Return to contents]](#Contents)
## Digest
## str
```v
fn (d Digest) str() string
```
string makes a formatted string representation of a Digest structure
[[Return to contents]](#Contents)
## write
```v
fn (mut d Digest) write(data []u8) !
```
write adds bytes to the hash
[[Return to contents]](#Contents)
## checksum
```v
fn (mut d Digest) checksum() []u8
```
checksum finalizes the hash and returns the generated bytes.
[[Return to contents]](#Contents)
#### Powered by vdoc. Generated on: 2 Sep 2025 07:18:17

View File

@@ -0,0 +1,124 @@
# module blake3
## Contents
- [Constants](#Constants)
- [sum256](#sum256)
- [sum_derive_key256](#sum_derive_key256)
- [sum_keyed256](#sum_keyed256)
- [Digest.new_derive_key_hash](#Digest.new_derive_key_hash)
- [Digest.new_hash](#Digest.new_hash)
- [Digest.new_keyed_hash](#Digest.new_keyed_hash)
- [Digest](#Digest)
- [write](#write)
- [checksum](#checksum)
## Constants
```v
const size256 = 32
```
size256 is the size, in bytes, of a Blake3 256 checksum.
[[Return to contents]](#Contents)
```v
const key_length = 32
```
key_length is the length, in bytes, of a Blake3 key
[[Return to contents]](#Contents)
```v
const block_size = 64
```
block_size is the block size, in bytes, of the Blake3 hash functions.
[[Return to contents]](#Contents)
```v
const chunk_size = 1024
```
chunk_size is the chunk size, in bytes, of the Blake3 hash functions. A chunk consists of 16 blocks.
[[Return to contents]](#Contents)
## sum256
```v
fn sum256(data []u8) []u8
```
sum256 returns the Blake3 256 bit hash of the data.
[[Return to contents]](#Contents)
## sum_derive_key256
```v
fn sum_derive_key256(context []u8, key_material []u8) []u8
```
sum_derived_key256 returns the Blake3 256 bit derived key hash of the key material
[[Return to contents]](#Contents)
## sum_keyed256
```v
fn sum_keyed256(data []u8, key []u8) []u8
```
sum_keyed256 returns the Blake3 256 bit keyed hash of the data.
[[Return to contents]](#Contents)
## Digest.new_derive_key_hash
```v
fn Digest.new_derive_key_hash(context []u8) !Digest
```
Digest.new_derive_key_hash initializes a Digest structure for deriving a Blake3 key
[[Return to contents]](#Contents)
## Digest.new_hash
```v
fn Digest.new_hash() !Digest
```
Digest.new_hash initializes a Digest structure for a Blake3 hash
[[Return to contents]](#Contents)
## Digest.new_keyed_hash
```v
fn Digest.new_keyed_hash(key []u8) !Digest
```
Digest.new_keyed_hash initializes a Digest structure for a Blake3 keyed hash
[[Return to contents]](#Contents)
## Digest
## write
```v
fn (mut d Digest) write(data []u8) !
```
write adds bytes to the hash
[[Return to contents]](#Contents)
## checksum
```v
fn (mut d Digest) checksum(size u64) []u8
```
checksum finalizes the hash and returns the generated bytes.
This is the point in the hashing operation that we need to know how many bytes of hash to generate. Normally this is 32 but can be any size up to 2**64.
[[Return to contents]](#Contents)
#### Powered by vdoc. Generated on: 2 Sep 2025 07:18:17

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,238 @@
# module cipher
## Contents
- [new_cbc](#new_cbc)
- [new_cfb_decrypter](#new_cfb_decrypter)
- [new_cfb_encrypter](#new_cfb_encrypter)
- [new_ctr](#new_ctr)
- [new_ofb](#new_ofb)
- [safe_xor_bytes](#safe_xor_bytes)
- [xor_bytes](#xor_bytes)
- [xor_words](#xor_words)
- [Block](#Block)
- [BlockMode](#BlockMode)
- [Stream](#Stream)
- [Cbc](#Cbc)
- [free](#free)
- [encrypt_blocks](#encrypt_blocks)
- [decrypt_blocks](#decrypt_blocks)
- [Cfb](#Cfb)
- [free](#free)
- [xor_key_stream](#xor_key_stream)
- [Ctr](#Ctr)
- [free](#free)
- [xor_key_stream](#xor_key_stream)
- [Ofb](#Ofb)
- [xor_key_stream](#xor_key_stream)
## new_cbc
```v
fn new_cbc(b Block, iv []u8) Cbc
```
new_cbc returns a `DesCbc` which encrypts in cipher block chaining mode, using the given Block. The length of iv must be the same as the Block's block size.
[[Return to contents]](#Contents)
## new_cfb_decrypter
```v
fn new_cfb_decrypter(b Block, iv []u8) Cfb
```
new_cfb_decrypter returns a `Cfb` which decrypts with cipher feedback mode, using the given Block. The iv must be the same length as the Block's block size
[[Return to contents]](#Contents)
## new_cfb_encrypter
```v
fn new_cfb_encrypter(b Block, iv []u8) Cfb
```
new_cfb_encrypter returns a `Cfb` which encrypts with cipher feedback mode, using the given Block. The iv must be the same length as the Block's block size
[[Return to contents]](#Contents)
## new_ctr
```v
fn new_ctr(b Block, iv []u8) Ctr
```
new_ctr returns a Ctr which encrypts/decrypts using the given Block in counter mode. The length of iv must be the same as the Block's block size.
[[Return to contents]](#Contents)
## new_ofb
```v
fn new_ofb(b Block, iv []u8) Ofb
```
new_ofb returns a Ofb that encrypts or decrypts using the block cipher b in output feedback mode. The initialization vector iv's length must be equal to b's block size.
[[Return to contents]](#Contents)
## safe_xor_bytes
```v
fn safe_xor_bytes(mut dst []u8, a []u8, b []u8, n int)
```
safe_xor_bytes XORs the bytes in `a` and `b` into `dst` it does so `n` times. Please note: `n` needs to be smaller or equal than the length of `a` and `b`.
[[Return to contents]](#Contents)
## xor_bytes
```v
fn xor_bytes(mut dst []u8, a []u8, b []u8) int
```
Note: Implement other versions (joe-c)xor_bytes xors the bytes in a and b. The destination should have enough space, otherwise xor_bytes will panic. Returns the number of bytes xor'd.
[[Return to contents]](#Contents)
## xor_words
```v
fn xor_words(mut dst []u8, a []u8, b []u8)
```
xor_words XORs multiples of 4 or 8 bytes (depending on architecture.) The slice arguments `a` and `b` are assumed to be of equal length.
[[Return to contents]](#Contents)
## Block
```v
interface Block {
block_size int // block_size returns the cipher's block size.
encrypt(mut dst []u8, src []u8) // Encrypt encrypts the first block in src into dst.
// Dst and src must overlap entirely or not at all.
decrypt(mut dst []u8, src []u8) // Decrypt decrypts the first block in src into dst.
// Dst and src must overlap entirely or not at all.
}
```
A Block represents an implementation of block cipher using a given key. It provides the capability to encrypt or decrypt individual blocks. The mode implementations extend that capability to streams of blocks.
[[Return to contents]](#Contents)
## BlockMode
```v
interface BlockMode {
block_size int // block_size returns the mode's block size.
crypt_blocks(mut dst []u8, src []u8) // crypt_blocks encrypts or decrypts a number of blocks. The length of
// src must be a multiple of the block size. Dst and src must overlap
// entirely or not at all.
//
// If len(dst) < len(src), crypt_blocks should panic. It is acceptable
// to pass a dst bigger than src, and in that case, crypt_blocks will
// only update dst[:len(src)] and will not touch the rest of dst.
//
// Multiple calls to crypt_blocks behave as if the concatenation of
// the src buffers was passed in a single run. That is, BlockMode
// maintains state and does not reset at each crypt_blocks call.
}
```
A BlockMode represents a block cipher running in a block-based mode (CBC, ECB etc).
[[Return to contents]](#Contents)
## Stream
```v
interface Stream {
mut:
// xor_key_stream XORs each byte in the given slice with a byte from the
// cipher's key stream. Dst and src must overlap entirely or not at all.
//
// If len(dst) < len(src), xor_key_stream should panic. It is acceptable
// to pass a dst bigger than src, and in that case, xor_key_stream will
// only update dst[:len(src)] and will not touch the rest of dst.
//
// Multiple calls to xor_key_stream behave as if the concatenation of
// the src buffers was passed in a single run. That is, Stream
// maintains state and does not reset at each xor_key_stream call.
xor_key_stream(mut dst []u8, src []u8)
}
```
A Stream represents a stream cipher.
[[Return to contents]](#Contents)
## Cbc
## free
```v
fn (mut x Cbc) free()
```
free the resources taken by the Cbc `x`
[[Return to contents]](#Contents)
## encrypt_blocks
```v
fn (mut x Cbc) encrypt_blocks(mut dst_ []u8, src_ []u8)
```
encrypt_blocks encrypts the blocks in `src_` to `dst_`. Please note: `dst_` is mutable for performance reasons.
[[Return to contents]](#Contents)
## decrypt_blocks
```v
fn (mut x Cbc) decrypt_blocks(mut dst []u8, src []u8)
```
decrypt_blocks decrypts the blocks in `src` to `dst`. Please note: `dst` is mutable for performance reasons.
[[Return to contents]](#Contents)
## Cfb
## free
```v
fn (mut x Cfb) free()
```
free the resources taken by the Cfb `x`
[[Return to contents]](#Contents)
## xor_key_stream
```v
fn (mut x Cfb) xor_key_stream(mut dst []u8, src []u8)
```
xor_key_stream xors each byte in the given slice with a byte from the key stream.
[[Return to contents]](#Contents)
## Ctr
## free
```v
fn (mut x Ctr) free()
```
free the resources taken by the Ctr `c`
[[Return to contents]](#Contents)
## xor_key_stream
```v
fn (mut x Ctr) xor_key_stream(mut dst []u8, src []u8)
```
xor_key_stream xors each byte in the given slice with a byte from the key stream.
[[Return to contents]](#Contents)
## Ofb
## xor_key_stream
```v
fn (mut x Ofb) xor_key_stream(mut dst []u8, src []u8)
```
xor_key_stream xors each byte in the given slice with a byte from the key stream.
[[Return to contents]](#Contents)
#### Powered by vdoc. Generated on: 2 Sep 2025 07:18:17

View File

@@ -0,0 +1,613 @@
# module crypto.ed25519.internal.edwards25519
## Contents
- [Constants](#Constants)
- [new_generator_point](#new_generator_point)
- [new_identity_point](#new_identity_point)
- [new_scalar](#new_scalar)
- [Scalar](#Scalar)
- [add](#add)
- [bytes](#bytes)
- [equal](#equal)
- [invert](#invert)
- [multiply](#multiply)
- [multiply_add](#multiply_add)
- [negate](#negate)
- [non_adjacent_form](#non_adjacent_form)
- [set](#set)
- [set_bytes_with_clamping](#set_bytes_with_clamping)
- [set_canonical_bytes](#set_canonical_bytes)
- [set_uniform_bytes](#set_uniform_bytes)
- [subtract](#subtract)
- [Element](#Element)
- [zero](#zero)
- [one](#one)
- [reduce](#reduce)
- [add](#add)
- [subtract](#subtract)
- [negate](#negate)
- [invert](#invert)
- [square](#square)
- [multiply](#multiply)
- [pow_22523](#pow_22523)
- [sqrt_ratio](#sqrt_ratio)
- [selected](#selected)
- [is_negative](#is_negative)
- [absolute](#absolute)
- [set](#set)
- [set_bytes](#set_bytes)
- [bytes](#bytes)
- [equal](#equal)
- [swap](#swap)
- [mult_32](#mult_32)
- [Point](#Point)
- [add](#add)
- [bytes](#bytes)
- [bytes_montgomery](#bytes_montgomery)
- [equal](#equal)
- [mult_by_cofactor](#mult_by_cofactor)
- [multi_scalar_mult](#multi_scalar_mult)
- [negate](#negate)
- [scalar_base_mult](#scalar_base_mult)
- [scalar_mult](#scalar_mult)
- [set](#set)
- [set_bytes](#set_bytes)
- [subtract](#subtract)
- [vartime_double_scalar_base_mult](#vartime_double_scalar_base_mult)
- [vartime_multiscalar_mult](#vartime_multiscalar_mult)
## Constants
```v
const sc_zero = Scalar{
s: [u8(0), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0]!
}
```
[[Return to contents]](#Contents)
```v
const sc_one = Scalar{
s: [u8(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0]!
}
```
[[Return to contents]](#Contents)
```v
const sc_minus_one = Scalar{
s: [u8(236), 211, 245, 92, 26, 99, 18, 88, 214, 156, 247, 162, 222, 249, 222, 20, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16]!
}
```
[[Return to contents]](#Contents)
## new_generator_point
```v
fn new_generator_point() Point
```
new_generator_point returns a new Point set to the canonical generator.
[[Return to contents]](#Contents)
## new_identity_point
```v
fn new_identity_point() Point
```
new_identity_point returns a new Point set to the identity.
[[Return to contents]](#Contents)
## new_scalar
```v
fn new_scalar() Scalar
```
new_scalar return new zero scalar
[[Return to contents]](#Contents)
## Scalar
## add
```v
fn (mut s Scalar) add(x Scalar, y Scalar) Scalar
```
add sets s = x + y mod l, and returns s.
[[Return to contents]](#Contents)
## bytes
```v
fn (mut s Scalar) bytes() []u8
```
bytes returns the canonical 32-byte little-endian encoding of s.
[[Return to contents]](#Contents)
## equal
```v
fn (s Scalar) equal(t Scalar) int
```
equal returns 1 if s and t are equal, and 0 otherwise.
[[Return to contents]](#Contents)
## invert
```v
fn (mut s Scalar) invert(t Scalar) Scalar
```
invert sets s to the inverse of a nonzero scalar v, and returns s.
If t is zero, invert returns zero.
[[Return to contents]](#Contents)
## multiply
```v
fn (mut s Scalar) multiply(x Scalar, y Scalar) Scalar
```
multiply sets s = x * y mod l, and returns s.
[[Return to contents]](#Contents)
## multiply_add
```v
fn (mut s Scalar) multiply_add(x Scalar, y Scalar, z Scalar) Scalar
```
multiply_add sets s = x * y + z mod l, and returns s.
[[Return to contents]](#Contents)
## negate
```v
fn (mut s Scalar) negate(x Scalar) Scalar
```
negate sets s = -x mod l, and returns s.
[[Return to contents]](#Contents)
## non_adjacent_form
```v
fn (mut s Scalar) non_adjacent_form(w u32) []i8
```
non_adjacent_form computes a width-w non-adjacent form for this scalar.
w must be between 2 and 8, or non_adjacent_form will panic.
[[Return to contents]](#Contents)
## set
```v
fn (mut s Scalar) set(x Scalar) Scalar
```
set sets s = x, and returns s.
[[Return to contents]](#Contents)
## set_bytes_with_clamping
```v
fn (mut s Scalar) set_bytes_with_clamping(x []u8) !Scalar
```
set_bytes_with_clamping applies the buffer pruning described in RFC 8032, Section 5.1.5 (also known as clamping) and sets s to the result. The input must be 32 bytes, and it is not modified. If x is not of the right length, `set_bytes_with_clamping` returns an error, and the receiver is unchanged.
Note that since Scalar values are always reduced modulo the prime order of the curve, the resulting value will not preserve any of the cofactor-clearing properties that clamping is meant to provide. It will however work as expected as long as it is applied to points on the prime order subgroup, like in Ed25519. In fact, it is lost to history why RFC 8032 adopted the irrelevant RFC 7748 clamping, but it is now required for compatibility.
[[Return to contents]](#Contents)
## set_canonical_bytes
```v
fn (mut s Scalar) set_canonical_bytes(x []u8) !Scalar
```
set_canonical_bytes sets s = x, where x is a 32-byte little-endian encoding of s, and returns s. If x is not a canonical encoding of s, set_canonical_bytes returns an error, and the receiver is unchanged.
[[Return to contents]](#Contents)
## set_uniform_bytes
```v
fn (mut s Scalar) set_uniform_bytes(x []u8) !Scalar
```
set_uniform_bytes sets s to an uniformly distributed value given 64 uniformly distributed random bytes. If x is not of the right length, set_uniform_bytes returns an error, and the receiver is unchanged.
[[Return to contents]](#Contents)
## subtract
```v
fn (mut s Scalar) subtract(x Scalar, y Scalar) Scalar
```
subtract sets s = x - y mod l, and returns s.
[[Return to contents]](#Contents)
## Element
```v
struct Element {
mut:
// An element t represents the integer
// t.l0 + t.l1*2^51 + t.l2*2^102 + t.l3*2^153 + t.l4*2^204
//
// Between operations, all limbs are expected to be lower than 2^52.
l0 u64
l1 u64
l2 u64
l3 u64
l4 u64
}
```
Element represents an element of the edwards25519 GF(2^255-19). Note that this is not a cryptographically secure group, and should only be used to interact with edwards25519.Point coordinates.
This type works similarly to math/big.Int, and all arguments and receivers are allowed to alias.
The zero value is a valid zero element.
[[Return to contents]](#Contents)
## zero
```v
fn (mut v Element) zero() Element
```
zero sets v = 0, and returns v.
[[Return to contents]](#Contents)
## one
```v
fn (mut v Element) one() Element
```
one sets v = 1, and returns v.
[[Return to contents]](#Contents)
## reduce
```v
fn (mut v Element) reduce() Element
```
reduce reduces v modulo 2^255 - 19 and returns it.
[[Return to contents]](#Contents)
## add
```v
fn (mut v Element) add(a Element, b Element) Element
```
add sets v = a + b, and returns v.
[[Return to contents]](#Contents)
## subtract
```v
fn (mut v Element) subtract(a Element, b Element) Element
```
subtract sets v = a - b, and returns v.
[[Return to contents]](#Contents)
## negate
```v
fn (mut v Element) negate(a Element) Element
```
negate sets v = -a, and returns v.
[[Return to contents]](#Contents)
## invert
```v
fn (mut v Element) invert(z Element) Element
```
invert sets v = 1/z mod p, and returns v.
If z == 0, invert returns v = 0.
[[Return to contents]](#Contents)
## square
```v
fn (mut v Element) square(x Element) Element
```
square sets v = x * x, and returns v.
[[Return to contents]](#Contents)
## multiply
```v
fn (mut v Element) multiply(x Element, y Element) Element
```
multiply sets v = x * y, and returns v.
[[Return to contents]](#Contents)
## pow_22523
```v
fn (mut v Element) pow_22523(x Element) Element
```
pow_22523 set v = x^((p-5)/8), and returns v. (p-5)/8 is 2^252-3.
[[Return to contents]](#Contents)
## sqrt_ratio
```v
fn (mut r Element) sqrt_ratio(u Element, v Element) (Element, int)
```
sqrt_ratio sets r to the non-negative square root of the ratio of u and v.
If u/v is square, sqrt_ratio returns r and 1. If u/v is not square, sqrt_ratio sets r according to Section 4.3 of draft-irtf-cfrg-ristretto255-decaf448-00, and returns r and 0.
[[Return to contents]](#Contents)
## selected
```v
fn (mut v Element) selected(a Element, b Element, cond int) Element
```
selected sets v to a if cond == 1, and to b if cond == 0.
[[Return to contents]](#Contents)
## is_negative
```v
fn (mut v Element) is_negative() int
```
is_negative returns 1 if v is negative, and 0 otherwise.
[[Return to contents]](#Contents)
## absolute
```v
fn (mut v Element) absolute(u Element) Element
```
absolute sets v to |u|, and returns v.
[[Return to contents]](#Contents)
## set
```v
fn (mut v Element) set(a Element) Element
```
set sets v = a, and returns v.
[[Return to contents]](#Contents)
## set_bytes
```v
fn (mut v Element) set_bytes(x []u8) !Element
```
set_bytes sets v to x, where x is a 32-byte little-endian encoding. If x is not of the right length, SetUniformBytes returns an error, and the receiver is unchanged.
Consistent with RFC 7748, the most significant bit (the high bit of the last byte) is ignored, and non-canonical values (2^255-19 through 2^255-1) are accepted. Note that this is laxer than specified by RFC 8032.
[[Return to contents]](#Contents)
## bytes
```v
fn (mut v Element) bytes() []u8
```
bytes returns the canonical 32-byte little-endian encoding of v.
[[Return to contents]](#Contents)
## equal
```v
fn (mut v Element) equal(ue Element) int
```
equal returns 1 if v and u are equal, and 0 otherwise.
[[Return to contents]](#Contents)
## swap
```v
fn (mut v Element) swap(mut u Element, cond int)
```
swap swaps v and u if cond == 1 or leaves them unchanged if cond == 0, and returns v.
[[Return to contents]](#Contents)
## mult_32
```v
fn (mut v Element) mult_32(x Element, y u32) Element
```
mult_32 sets v = x * y, and returns v.
[[Return to contents]](#Contents)
## Point
```v
struct Point {
mut:
// The point is internally represented in extended coordinates (x, y, z, T)
// where x = x/z, y = y/z, and xy = T/z per https://eprint.iacr.org/2008/522.
x Element
y Element
z Element
t Element
// Make the type not comparable (i.e. used with == or as a map key), as
// equivalent points can be represented by different values.
// _ incomparable
}
```
Point represents a point on the edwards25519 curve.
This type works similarly to math/big.Int, and all arguments and receivers are allowed to alias.
The zero value is NOT valid, and it may be used only as a receiver.
[[Return to contents]](#Contents)
## add
```v
fn (mut v Point) add(p Point, q Point) Point
```
add sets v = p + q, and returns v.
[[Return to contents]](#Contents)
## bytes
```v
fn (mut v Point) bytes() []u8
```
bytes returns the canonical 32-byte encoding of v, according to RFC 8032, Section 5.1.2.
[[Return to contents]](#Contents)
## bytes_montgomery
```v
fn (mut v Point) bytes_montgomery() []u8
```
bytes_montgomery converts v to a point on the birationally-equivalent Curve25519 Montgomery curve, and returns its canonical 32 bytes encoding according to RFC 7748.
Note that bytes_montgomery only encodes the u-coordinate, so v and -v encode to the same value. If v is the identity point, bytes_montgomery returns 32 zero bytes, analogously to the X25519 function.
[[Return to contents]](#Contents)
## equal
```v
fn (mut v Point) equal(u Point) int
```
equal returns 1 if v is equivalent to u, and 0 otherwise.
[[Return to contents]](#Contents)
## mult_by_cofactor
```v
fn (mut v Point) mult_by_cofactor(p Point) Point
```
mult_by_cofactor sets v = 8 * p, and returns v.
[[Return to contents]](#Contents)
## multi_scalar_mult
```v
fn (mut v Point) multi_scalar_mult(scalars []Scalar, points []Point) Point
```
multi_scalar_mult sets v = sum(scalars[i] * points[i]), and returns v.
Execution time depends only on the lengths of the two slices, which must match.
[[Return to contents]](#Contents)
## negate
```v
fn (mut v Point) negate(p Point) Point
```
negate sets v = -p, and returns v.
[[Return to contents]](#Contents)
## scalar_base_mult
```v
fn (mut v Point) scalar_base_mult(mut x Scalar) Point
```
scalar_base_mult sets v = x * B, where B is the canonical generator, and returns v.
The scalar multiplication is done in constant time.
[[Return to contents]](#Contents)
## scalar_mult
```v
fn (mut v Point) scalar_mult(mut x Scalar, q Point) Point
```
scalar_mult sets v = x * q, and returns v.
The scalar multiplication is done in constant time.
[[Return to contents]](#Contents)
## set
```v
fn (mut v Point) set(u Point) Point
```
set sets v = u, and returns v.
[[Return to contents]](#Contents)
## set_bytes
```v
fn (mut v Point) set_bytes(x []u8) !Point
```
set_bytes sets v = x, where x is a 32-byte encoding of v. If x does not represent a valid point on the curve, set_bytes returns an error and the receiver is unchanged. Otherwise, set_bytes returns v.
Note that set_bytes accepts all non-canonical encodings of valid points. That is, it follows decoding rules that match most implementations in the ecosystem rather than RFC 8032.
[[Return to contents]](#Contents)
## subtract
```v
fn (mut v Point) subtract(p Point, q Point) Point
```
subtract sets v = p - q, and returns v.
[[Return to contents]](#Contents)
## vartime_double_scalar_base_mult
```v
fn (mut v Point) vartime_double_scalar_base_mult(xa Scalar, aa Point, xb Scalar) Point
```
vartime_double_scalar_base_mult sets v = a * A + b * B, where B is the canonical generator, and returns v.
Execution time depends on the inputs.
[[Return to contents]](#Contents)
## vartime_multiscalar_mult
```v
fn (mut v Point) vartime_multiscalar_mult(scalars []Scalar, points []Point) Point
```
vartime_multiscalar_mult sets v = sum(scalars[i] * points[i]), and returns v.
Execution time depends on the inputs.
[[Return to contents]](#Contents)
#### Powered by vdoc. Generated on: 2 Sep 2025 07:18:17

View File

@@ -0,0 +1,90 @@
# module crypto.internal.subtle
## Contents
- [any_overlap](#any_overlap)
- [constant_time_byte_eq](#constant_time_byte_eq)
- [constant_time_compare](#constant_time_compare)
- [constant_time_copy](#constant_time_copy)
- [constant_time_eq](#constant_time_eq)
- [constant_time_less_or_eq](#constant_time_less_or_eq)
- [constant_time_select](#constant_time_select)
- [inexact_overlap](#inexact_overlap)
## any_overlap
```v
fn any_overlap(x []u8, y []u8) bool
```
Note: require unsafe in futureany_overlap reports whether x and y share memory at any (not necessarily corresponding) index. The memory beyond the slice length is ignored.
[[Return to contents]](#Contents)
## constant_time_byte_eq
```v
fn constant_time_byte_eq(x u8, y u8) int
```
constant_time_byte_eq returns 1 when x == y.
[[Return to contents]](#Contents)
## constant_time_compare
```v
fn constant_time_compare(x []u8, y []u8) int
```
constant_time_compare returns 1 when x and y have equal contents. The runtime of this function is proportional of the length of x and y. It is *NOT* dependent on their content.
[[Return to contents]](#Contents)
## constant_time_copy
```v
fn constant_time_copy(v int, mut x []u8, y []u8)
```
constant_time_copy copies the contents of y into x, when v == 1. When v == 0, x is left unchanged. this function is undefined, when v takes any other value
[[Return to contents]](#Contents)
## constant_time_eq
```v
fn constant_time_eq(x int, y int) int
```
constant_time_eq returns 1 when x == y.
[[Return to contents]](#Contents)
## constant_time_less_or_eq
```v
fn constant_time_less_or_eq(x int, y int) int
```
constant_time_less_or_eq returns 1 if x <= y, and 0 otherwise. it is undefined when x or y are negative, or > (2^32 - 1)
[[Return to contents]](#Contents)
## constant_time_select
```v
fn constant_time_select(v int, x int, y int) int
```
constant_time_select returns x when v == 1, and y when v == 0. it is undefined when v is any other value
[[Return to contents]](#Contents)
## inexact_overlap
```v
fn inexact_overlap(x []u8, y []u8) bool
```
inexact_overlap reports whether x and y share memory at any non-corresponding index. The memory beyond the slice length is ignored. Note that x and y can have different lengths and still not have any inexact overlap.
inexact_overlap can be used to implement the requirements of the crypto/cipher AEAD, Block, BlockMode and Stream interfaces.
[[Return to contents]](#Contents)
#### Powered by vdoc. Generated on: 2 Sep 2025 07:18:17

View File

@@ -0,0 +1,34 @@
# module crypto
## Contents
- [Hash](#Hash)
## Hash
```v
enum Hash {
md4
md5
sha1
sha224
sha256
sha384
sha512
md5sha1
ripemd160
sha3_224
sha3_256
sha3_384
sha3_512
sha512_224
sha512_256
blake2s_256
blake2b_256
blake2b_384
blake2b_512
}
```
[[Return to contents]](#Contents)
#### Powered by vdoc. Generated on: 2 Sep 2025 07:18:17

View File

@@ -0,0 +1,80 @@
# module des
## Contents
- [encrypt_block](#encrypt_block)
- [new_cipher](#new_cipher)
- [new_triple_des_cipher](#new_triple_des_cipher)
- [DesCipher](#DesCipher)
- [encrypt](#encrypt)
- [decrypt](#decrypt)
- [TripleDesCipher](#TripleDesCipher)
- [encrypt](#encrypt)
- [decrypt](#decrypt)
## encrypt_block
```v
fn encrypt_block(subkeys []u64, mut dst []u8, src []u8)
```
Encrypt one block from src into dst, using the subkeys.
[[Return to contents]](#Contents)
## new_cipher
```v
fn new_cipher(key []u8) cipher.Block
```
NewCipher creates and returns a new cipher.Block.
[[Return to contents]](#Contents)
## new_triple_des_cipher
```v
fn new_triple_des_cipher(key []u8) cipher.Block
```
NewTripleDesCipher creates and returns a new cipher.Block.
[[Return to contents]](#Contents)
## DesCipher
## encrypt
```v
fn (c &DesCipher) encrypt(mut dst []u8, src []u8)
```
encrypt a block of data using the DES algorithm
[[Return to contents]](#Contents)
## decrypt
```v
fn (c &DesCipher) decrypt(mut dst []u8, src []u8)
```
decrypt a block of data using the DES algorithm
[[Return to contents]](#Contents)
## TripleDesCipher
## encrypt
```v
fn (c &TripleDesCipher) encrypt(mut dst []u8, src []u8)
```
encrypt a block of data using the TripleDES algorithm
[[Return to contents]](#Contents)
## decrypt
```v
fn (c &TripleDesCipher) decrypt(mut dst []u8, src []u8)
```
decrypt a block of data using the TripleDES algorithm
[[Return to contents]](#Contents)
#### Powered by vdoc. Generated on: 2 Sep 2025 07:18:17

View File

@@ -0,0 +1,304 @@
# module ecdsa
## Contents
- [generate_key](#generate_key)
- [new_key_from_seed](#new_key_from_seed)
- [privkey_from_string](#privkey_from_string)
- [pubkey_from_bytes](#pubkey_from_bytes)
- [pubkey_from_string](#pubkey_from_string)
- [PrivateKey.new](#PrivateKey.new)
- [HashConfig](#HashConfig)
- [Nid](#Nid)
- [C.BIO](#C.BIO)
- [CurveOptions](#CurveOptions)
- [PrivateKey](#PrivateKey)
- [sign](#sign)
- [sign_with_options](#sign_with_options)
- [bytes](#bytes)
- [seed](#seed)
- [public_key](#public_key)
- [equal](#equal)
- [free](#free)
- [PublicKey](#PublicKey)
- [bytes](#bytes)
- [equal](#equal)
- [free](#free)
- [verify](#verify)
- [SignerOpts](#SignerOpts)
## generate_key
```v
fn generate_key(opt CurveOptions) !(PublicKey, PrivateKey)
```
generate_key generates a new key pair. If opt was not provided, its default to prime256v1 curve. If you want another curve, use `pubkey, pivkey := ecdsa.generate_key(nid: .secp384r1)!` instead.
[[Return to contents]](#Contents)
## new_key_from_seed
```v
fn new_key_from_seed(seed []u8, opt CurveOptions) !PrivateKey
```
new_key_from_seed creates a new private key from the seed bytes. If opt was not provided, its default to prime256v1 curve.
Notes on the seed:
You should make sure, the seed bytes come from a cryptographically secure random generator, likes the `crypto.rand` or other trusted sources. Internally, the seed size's would be checked to not exceed the key size of underlying curve, ie, 32 bytes length for p-256 and secp256k1, 48 bytes length for p-384 and 66 bytes length for p-521. Its recommended to use seed with bytes length matching with underlying curve key size.
[[Return to contents]](#Contents)
## privkey_from_string
```v
fn privkey_from_string(s string) !PrivateKey
```
privkey_from_string loads a PrivateKey from valid PEM-formatted string in s. Underlying wrapper support for old SECG and PKCS8 private key format, but this was not heavily tested. This routine does not support for the PKCS8 EncryptedPrivateKeyInfo format. See [ecdsa_seed_test.v](https://github.com/vlang/v/blob/master/vlib/crypto/ecdsa/example/ecdsa_seed_test.v) file for example of usage.
[[Return to contents]](#Contents)
## pubkey_from_bytes
```v
fn pubkey_from_bytes(bytes []u8) !PublicKey
```
pubkey_from_bytes loads ECDSA Public Key from bytes array. The bytes of data should be a valid of ASN.1 DER serialized SubjectPublicKeyInfo structrue of RFC 5480. Otherwise, its should an error. Typically, you can load the bytes from pem formatted of ecdsa public key.
Examples:
```codeblock
import crypto.pem
import crypto.ecdsa
const pubkey_sample = '-----BEGIN PUBLIC KEY-----
MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE+P3rhFkT1fXHYbY3CpcBdh6xTC74MQFx
cftNVD3zEPVzo//OalIVatY162ksg8uRWBdvFFuHZ9OMVXkbjwWwhcXP7qmI9rOS
LR3AGUldy+bBpV2nT306qCIwgUAMeOJP
-----END PUBLIC KEY-----'
block, _ := pem.decode(pubkey_sample) or { panic(err) }
pubkey := ecdsa.pubkey_from_bytes(block.data)!
```
[[Return to contents]](#Contents)
## pubkey_from_string
```v
fn pubkey_from_string(s string) !PublicKey
```
pubkey_from_string loads a PublicKey from valid PEM-formatted string in s.
[[Return to contents]](#Contents)
## PrivateKey.new
```v
fn PrivateKey.new(opt CurveOptions) !PrivateKey
```
PrivateKey.new creates a new key pair. By default, it would create a prime256v1 based key. Dont forget to call `.free()` after finish with your key.
[[Return to contents]](#Contents)
## HashConfig
```v
enum HashConfig {
with_recommended_hash
with_no_hash
with_custom_hash
}
```
HashConfig is an enumeration of the possible options for key signing (verifying).
[[Return to contents]](#Contents)
## Nid
```v
enum Nid {
prime256v1 = C.NID_X9_62_prime256v1
secp384r1 = C.NID_secp384r1
secp521r1 = C.NID_secp521r1
secp256k1 = C.NID_secp256k1
}
```
Nid is an enumeration of the supported curves
[[Return to contents]](#Contents)
## C.BIO
```v
struct C.BIO {}
```
[[Return to contents]](#Contents)
## CurveOptions
```v
struct CurveOptions {
pub mut:
// default to NIST P-256 curve
nid Nid = .prime256v1
// by default, allow arbitrary size of seed bytes as key.
// Set it to `true` when you need fixed size, using the curve key size.
// Its main purposes is to support the `.new_key_from_seed` call.
fixed_size bool
}
```
CurveOptions represents configuration options to drive keypair generation.
[[Return to contents]](#Contents)
## PrivateKey
```v
struct PrivateKey {
// The new high level of keypair opaque
evpkey &C.EVP_PKEY
mut:
// ks_flag with .flexible value allowing
// flexible-size seed bytes as key.
// When it is `.fixed`, it will use the underlying key size.
ks_flag KeyFlag = .flexible
// ks_size stores size of the seed bytes when ks_flag was .flexible.
// You should set it to a non zero value
ks_size int
}
```
PrivateKey represents ECDSA private key. Actually its a key pair, contains private key and public key parts.
[[Return to contents]](#Contents)
## sign
```v
fn (pv PrivateKey) sign(message []u8, opt SignerOpts) ![]u8
```
sign performs signing the message with the options. By default options, it will perform hashing before signing the message.
[[Return to contents]](#Contents)
## sign_with_options
```v
fn (pv PrivateKey) sign_with_options(message []u8, opt SignerOpts) ![]u8
```
sign_with_options signs message with the options. It will be deprecated, Use `PrivateKey.sign()` instead.
[[Return to contents]](#Contents)
## bytes
```v
fn (pv PrivateKey) bytes() ![]u8
```
bytes represent private key as bytes.
[[Return to contents]](#Contents)
## seed
```v
fn (pv PrivateKey) seed() ![]u8
```
seed gets the seed (private key bytes). It will be deprecated. Use `PrivateKey.bytes()` instead.
[[Return to contents]](#Contents)
## public_key
```v
fn (pv PrivateKey) public_key() !PublicKey
```
public_key gets the PublicKey from private key.
[[Return to contents]](#Contents)
## equal
```v
fn (priv_key PrivateKey) equal(other PrivateKey) bool
```
equal compares two private keys was equal.
[[Return to contents]](#Contents)
## free
```v
fn (pv &PrivateKey) free()
```
free clears out allocated memory for PrivateKey. Dont use PrivateKey after calling `.free()`
[[Return to contents]](#Contents)
## PublicKey
```v
struct PublicKey {
// The new high level of keypair opaque
evpkey &C.EVP_PKEY
}
```
PublicKey represents ECDSA public key for verifying message.
[[Return to contents]](#Contents)
## bytes
```v
fn (pbk PublicKey) bytes() ![]u8
```
bytes gets the bytes of public key.
[[Return to contents]](#Contents)
## equal
```v
fn (pub_key PublicKey) equal(other PublicKey) bool
```
equal compares two public keys was equal.
[[Return to contents]](#Contents)
## free
```v
fn (pb &PublicKey) free()
```
free clears out allocated memory for PublicKey. Dont use PublicKey after calling `.free()`
[[Return to contents]](#Contents)
## verify
```v
fn (pb PublicKey) verify(message []u8, sig []u8, opt SignerOpts) !bool
```
verify verifies a message with the signature are valid with public key provided . You should provide it with the same SignerOpts used with the `.sign()` call. or verify would fail (false).
[[Return to contents]](#Contents)
## SignerOpts
```v
struct SignerOpts {
pub mut:
// default to .with_recommended_hash
hash_config HashConfig = .with_recommended_hash
// make sense when HashConfig != with_recommended_hash
allow_smaller_size bool
allow_custom_hash bool
// set to non-nil if allow_custom_hash was true
custom_hash &hash.Hash = unsafe { nil }
}
```
SignerOpts represents configuration options to drive signing and verifying process.
[[Return to contents]](#Contents)
#### Powered by vdoc. Generated on: 2 Sep 2025 07:18:17

View File

@@ -0,0 +1,150 @@
# module ed25519
## Contents
- [Constants](#Constants)
- [generate_key](#generate_key)
- [new_key_from_seed](#new_key_from_seed)
- [sign](#sign)
- [verify](#verify)
- [PrivateKey](#PrivateKey)
- [seed](#seed)
- [public_key](#public_key)
- [equal](#equal)
- [sign](#sign)
- [PublicKey](#PublicKey)
- [equal](#equal)
## Constants
```v
const public_key_size = 32
```
public_key_size is the sizeof public keys in bytes
[[Return to contents]](#Contents)
```v
const private_key_size = 64
```
private_key_size is the sizeof private keys in bytes
[[Return to contents]](#Contents)
```v
const signature_size = 64
```
signature_size is the size of signatures generated and verified by this modules, in bytes.
[[Return to contents]](#Contents)
```v
const seed_size = 32
```
seed_size is the size of private key seeds in bytes
[[Return to contents]](#Contents)
## generate_key
```v
fn generate_key() !(PublicKey, PrivateKey)
```
generate_key generates a public/private key pair entropy using `crypto.rand`.
[[Return to contents]](#Contents)
## new_key_from_seed
```v
fn new_key_from_seed(seed []u8) PrivateKey
```
new_key_from_seed calculates a private key from a seed. private keys of RFC 8032 correspond to seeds in this module
[[Return to contents]](#Contents)
## sign
```v
fn sign(privatekey PrivateKey, message []u8) ![]u8
```
sign`signs the message with privatekey and returns a signature
[[Return to contents]](#Contents)
## verify
```v
fn verify(publickey PublicKey, message []u8, sig []u8) !bool
```
verify reports whether sig is a valid signature of message by publickey.
[[Return to contents]](#Contents)
## PrivateKey
```v
type PrivateKey = []u8
```
PrivateKey is Ed25519 private keys
[[Return to contents]](#Contents)
## seed
```v
fn (priv PrivateKey) seed() []u8
```
seed returns the private key seed corresponding to priv. RFC 8032's private keys correspond to seeds in this module.
[[Return to contents]](#Contents)
## public_key
```v
fn (priv PrivateKey) public_key() PublicKey
```
public_key returns the []u8 corresponding to priv.
[[Return to contents]](#Contents)
## equal
```v
fn (priv PrivateKey) equal(x []u8) bool
```
currentyly x not `crypto.PrivateKey`
[[Return to contents]](#Contents)
## sign
```v
fn (priv PrivateKey) sign(message []u8) ![]u8
```
sign signs the given message with priv.
[[Return to contents]](#Contents)
## PublicKey
```v
type PublicKey = []u8
```
`PublicKey` is Ed25519 public keys.
[[Return to contents]](#Contents)
## equal
```v
fn (p PublicKey) equal(x []u8) bool
```
equal reports whether p and x have the same value.
[[Return to contents]](#Contents)
#### Powered by vdoc. Generated on: 2 Sep 2025 07:18:17

View File

@@ -0,0 +1,28 @@
# module hmac
## Contents
- [equal](#equal)
- [new](#new)
## equal
```v
fn equal(mac1 []u8, mac2 []u8) bool
```
equal compares 2 MACs for equality, without leaking timing info.
Note: if the lengths of the 2 MACs are different, probably a completely different hash function was used to generate them => no useful timing information.
[[Return to contents]](#Contents)
## new
```v
fn new(key []u8, data []u8, hash_func fn ([]u8) []u8, blocksize int) []u8
```
new returns a HMAC byte array, depending on the hash algorithm used.
[[Return to contents]](#Contents)
#### Powered by vdoc. Generated on: 2 Sep 2025 07:18:17

View File

@@ -0,0 +1,123 @@
# module md5
## Contents
- [Constants](#Constants)
- [hexhash](#hexhash)
- [new](#new)
- [sum](#sum)
- [Digest](#Digest)
- [free](#free)
- [reset](#reset)
- [write](#write)
- [sum](#sum)
- [size](#size)
- [block_size](#block_size)
## Constants
```v
const size = 16
```
The size of an MD5 checksum in bytes.
[[Return to contents]](#Contents)
```v
const block_size = 64
```
The blocksize of MD5 in bytes.
[[Return to contents]](#Contents)
## hexhash
```v
fn hexhash(s string) string
```
hexhash returns a hexadecimal MD5 hash sum `string` of `s`.
Example
```v
assert md5.hexhash('V') == '5206560a306a2e085a437fd258eb57ce'
```
[[Return to contents]](#Contents)
## new
```v
fn new() &Digest
```
new returns a new Digest (implementing hash.Hash) computing the MD5 checksum.
[[Return to contents]](#Contents)
## sum
```v
fn sum(data []u8) []u8
```
sum returns the MD5 checksum of the data.
[[Return to contents]](#Contents)
## Digest
## free
```v
fn (mut d Digest) free()
```
free the resources taken by the Digest `d`
[[Return to contents]](#Contents)
## reset
```v
fn (mut d Digest) reset()
```
reset the state of the Digest `d`
[[Return to contents]](#Contents)
## write
```v
fn (mut d Digest) write(p_ []u8) !int
```
write writes the contents of `p_` to the internal hash representation.
[[Return to contents]](#Contents)
## sum
```v
fn (d &Digest) sum(b_in []u8) []u8
```
sum returns the md5 sum of the bytes in `b_in`.
[[Return to contents]](#Contents)
## size
```v
fn (d &Digest) size() int
```
size returns the size of the checksum in bytes.
[[Return to contents]](#Contents)
## block_size
```v
fn (d &Digest) block_size() int
```
block_size returns the block size of the checksum in bytes.
[[Return to contents]](#Contents)
#### Powered by vdoc. Generated on: 2 Sep 2025 07:18:17

View File

@@ -0,0 +1,16 @@
# module pbkdf2
## Contents
- [key](#key)
## key
```v
fn key(password []u8, salt []u8, count int, key_length int, h hash.Hash) ![]u8
```
key derives a key from the password, salt and iteration count example pbkdf2.key('test'.bytes(), '123456'.bytes(), 1000, 64, sha512.new())
[[Return to contents]](#Contents)
#### Powered by vdoc. Generated on: 2 Sep 2025 07:18:17

View File

@@ -0,0 +1,137 @@
# module pem
## Contents
- [decode](#decode)
- [decode_only](#decode_only)
- [Block.new](#Block.new)
- [Header](#Header)
- [str](#str)
- [Block](#Block)
- [encode](#encode)
- [free](#free)
- [header_by_key](#header_by_key)
- [EncodeConfig](#EncodeConfig)
## decode
```v
fn decode(data string) ?(Block, string)
```
decode reads `data` and returns the first parsed PEM Block along with the rest of the string. `none` is returned when a header is expected, but not present or when a start of '-----BEGIN' or end of '-----END' can't be found.
use decode_only if you do not need the unparsed rest of the string.
[[Return to contents]](#Contents)
## decode_only
```v
fn decode_only(data string) ?Block
```
decode_only reads `data` and returns the first parsed PEM Block. `none` is returned when a header is expected, but not present or when a start of '-----BEGIN' or end of '-----END' can't be found.
use decode if you still need the unparsed rest of the string.
[[Return to contents]](#Contents)
## Block.new
```v
fn Block.new(block_type string) Block
```
Block.new returns a new `Block` with the specified block_type
[[Return to contents]](#Contents)
## Header
```v
enum Header {
proctype
contentdomain
dekinfo
origid_asymm
origid_symm
recipid_asymm
recipid_symm
cert
issuercert
micinfo
keyinfo
crl
}
```
Headers as described in RFC 1421 Section 9
[[Return to contents]](#Contents)
## str
```v
fn (header Header) str() string
```
str returns the string representation of the header
[[Return to contents]](#Contents)
## Block
```v
struct Block {
pub mut:
// from preamble
block_type string
// optional headers
headers map[string][]string
// decoded contents
data []u8
}
```
[[Return to contents]](#Contents)
## encode
```v
fn (block Block) encode(config EncodeConfig) !string
```
encode encodes the given block into a string using the EncodeConfig. It returns an error if `block_type` is undefined or if a value in `headers` contains an invalid character ':'
default EncodeConfig values wrap lines at 64 bytes and use '\n' for newlines
[[Return to contents]](#Contents)
## free
```v
fn (mut block Block) free()
```
free the resources taken by the Block `block`
[[Return to contents]](#Contents)
## header_by_key
```v
fn (block Block) header_by_key(key Header) []string
```
header_by_key returns the selected key using the Header enum
same as `block.headers[key.str()]`
[[Return to contents]](#Contents)
## EncodeConfig
```v
struct EncodeConfig {
pub mut:
// inner text wrap around
line_length int = 64
// line ending (alternatively '\r\n')
line_ending string = '\n'
}
```
[[Return to contents]](#Contents)
#### Powered by vdoc. Generated on: 2 Sep 2025 07:18:17

View File

@@ -0,0 +1,60 @@
# module rand
## Contents
- [bytes](#bytes)
- [int_big](#int_big)
- [int_u64](#int_u64)
- [read](#read)
- [ReadError](#ReadError)
- [msg](#msg)
## bytes
```v
fn bytes(bytes_needed int) ![]u8
```
bytes returns an array of `bytes_needed` random bytes.
Note: this call can block your program for a long period of time, if your system does not have access to enough entropy. See also rand.bytes(), if you do not need really random bytes, but instead pseudo random ones, from a pseudo random generator that can be seeded, and that is usually faster.
[[Return to contents]](#Contents)
## int_big
```v
fn int_big(n big.Integer) !big.Integer
```
int_big creates a random `big.Integer` with range [0, n) returns an error if `n` is 0 or negative.
[[Return to contents]](#Contents)
## int_u64
```v
fn int_u64(max u64) !u64
```
int_u64 returns a random unsigned 64-bit integer `u64` read from a real OS source of entropy.
[[Return to contents]](#Contents)
## read
```v
fn read(bytes_needed int) ![]u8
```
read returns an array of `bytes_needed` random bytes read from the OS.
[[Return to contents]](#Contents)
## ReadError
## msg
```v
fn (err ReadError) msg() string
```
msg returns the error message.
[[Return to contents]](#Contents)
#### Powered by vdoc. Generated on: 2 Sep 2025 07:18:17

View File

@@ -0,0 +1,50 @@
# module rc4
## Contents
- [new_cipher](#new_cipher)
- [Cipher](#Cipher)
- [free](#free)
- [reset](#reset)
- [xor_key_stream](#xor_key_stream)
## new_cipher
```v
fn new_cipher(key []u8) !&Cipher
```
new_cipher creates and returns a new Cipher. The key argument should be the RC4 key, at least 1 byte and at most 256 bytes.
[[Return to contents]](#Contents)
## Cipher
## free
```v
fn (mut c Cipher) free()
```
free the resources taken by the Cipher `c`
[[Return to contents]](#Contents)
## reset
```v
fn (mut c Cipher) reset()
```
reset zeros the key data and makes the Cipher unusable.good to com
Deprecated: Reset can't guarantee that the key will be entirely removed from the process's memory.
[[Return to contents]](#Contents)
## xor_key_stream
```v
fn (mut c Cipher) xor_key_stream(mut dst []u8, src []u8)
```
xor_key_stream sets dst to the result of XORing src with the key stream. Dst and src must overlap entirely or not at all.
[[Return to contents]](#Contents)
#### Powered by vdoc. Generated on: 2 Sep 2025 07:18:17

View File

@@ -0,0 +1,88 @@
# module ripemd160
## Contents
- [hexhash](#hexhash)
- [new](#new)
- [Digest](#Digest)
- [free](#free)
- [reset](#reset)
- [size](#size)
- [block_size](#block_size)
- [write](#write)
- [sum](#sum)
## hexhash
```v
fn hexhash(s string) string
```
hexhash returns a hexadecimal RIPEMD-160 hash sum `string` of `s`.
[[Return to contents]](#Contents)
## new
```v
fn new() &Digest
```
new returns a new Digest (implementing hash.Hash) computing the MD5 checksum.
[[Return to contents]](#Contents)
## Digest
## free
```v
fn (mut d Digest) free()
```
free the resources taken by the Digest `d`
[[Return to contents]](#Contents)
## reset
```v
fn (mut d Digest) reset()
```
reset the state of the Digest `d`
[[Return to contents]](#Contents)
## size
```v
fn (d &Digest) size() int
```
size returns the size of the checksum in bytes.
[[Return to contents]](#Contents)
## block_size
```v
fn (d &Digest) block_size() int
```
block_size returns the block size of the checksum in bytes.
[[Return to contents]](#Contents)
## write
```v
fn (mut d Digest) write(p_ []u8) !int
```
write writes the contents of `p_` to the internal hash representation.
[[Return to contents]](#Contents)
## sum
```v
fn (d0 &Digest) sum(inp []u8) []u8
```
sum returns the RIPEMD-160 sum of the bytes in `inp`.
[[Return to contents]](#Contents)
#### Powered by vdoc. Generated on: 2 Sep 2025 07:18:17

View File

@@ -0,0 +1,36 @@
# module scrypt
## Contents
- [Constants](#Constants)
- [scrypt](#scrypt)
## Constants
```v
const max_buffer_length = ((u64(1) << 32) - 1) * 32
```
[[Return to contents]](#Contents)
```v
const max_blocksize_parallal_product = u64(1 << 30)
```
[[Return to contents]](#Contents)
## scrypt
```v
fn scrypt(password []u8, salt []u8, n u64, r u32, p u32, dk_len u64) ![]u8
```
scrypt performs password based key derivation using the scrypt algorithm.
The input parameters are:
password - a slice of bytes which is the password being used to derive the key. Don't leak this value to anybody. salt - a slice of bytes used to make it harder to crack the key. n - CPU/Memory cost parameter, must be larger than 0, a power of 2, and less than 2^(128 * r / 8). r - block size parameter. p - parallelization parameter, a positive integer less than or equal to ((2^32-1) * hLen) / MFLen where hLen is 32 and MFlen is 128 * r. dk_len - intended output length in octets of the derived key; a positive integer less than or equal to (2^32 - 1) * hLen where hLen is 32.
Reasonable values for n, r, and p are n = 1024, r = 8, p = 16.
[[Return to contents]](#Contents)
#### Powered by vdoc. Generated on: 2 Sep 2025 07:18:17

View File

@@ -0,0 +1,116 @@
# module sha1
## Contents
- [Constants](#Constants)
- [hexhash](#hexhash)
- [new](#new)
- [sum](#sum)
- [Digest](#Digest)
- [free](#free)
- [reset](#reset)
- [write](#write)
- [sum](#sum)
- [size](#size)
- [block_size](#block_size)
## Constants
```v
const size = 20
```
The size of a SHA-1 checksum in bytes.
[[Return to contents]](#Contents)
```v
const block_size = 64
```
The blocksize of SHA-1 in bytes.
[[Return to contents]](#Contents)
## hexhash
```v
fn hexhash(s string) string
```
hexhash returns a hexadecimal SHA1 hash sum `string` of `s`.
[[Return to contents]](#Contents)
## new
```v
fn new() &Digest
```
new returns a new Digest (implementing hash.Hash) computing the SHA1 checksum.
[[Return to contents]](#Contents)
## sum
```v
fn sum(data []u8) []u8
```
sum returns the SHA-1 checksum of the bytes passed in `data`.
[[Return to contents]](#Contents)
## Digest
## free
```v
fn (mut d Digest) free()
```
free the resources taken by the Digest `d`
[[Return to contents]](#Contents)
## reset
```v
fn (mut d Digest) reset()
```
reset the state of the Digest `d`
[[Return to contents]](#Contents)
## write
```v
fn (mut d Digest) write(p_ []u8) !int
```
write writes the contents of `p_` to the internal hash representation.
[[Return to contents]](#Contents)
## sum
```v
fn (d &Digest) sum(b_in []u8) []u8
```
sum returns a copy of the generated sum of the bytes in `b_in`.
[[Return to contents]](#Contents)
## size
```v
fn (d &Digest) size() int
```
size returns the size of the checksum in bytes.
[[Return to contents]](#Contents)
## block_size
```v
fn (d &Digest) block_size() int
```
block_size returns the block size of the checksum in bytes.
[[Return to contents]](#Contents)
#### Powered by vdoc. Generated on: 2 Sep 2025 07:18:17

View File

@@ -0,0 +1,178 @@
# module sha256
## Contents
- [Constants](#Constants)
- [hexhash](#hexhash)
- [hexhash_224](#hexhash_224)
- [new](#new)
- [new224](#new224)
- [sum](#sum)
- [sum224](#sum224)
- [sum256](#sum256)
- [Digest](#Digest)
- [free](#free)
- [reset](#reset)
- [write](#write)
- [sum](#sum)
- [size](#size)
- [block_size](#block_size)
## Constants
```v
const size = 32
```
The size of a SHA256 checksum in bytes.
[[Return to contents]](#Contents)
```v
const size224 = 28
```
The size of a SHA224 checksum in bytes.
[[Return to contents]](#Contents)
```v
const block_size = 64
```
The blocksize of SHA256 and SHA224 in bytes.
[[Return to contents]](#Contents)
## hexhash
```v
fn hexhash(s string) string
```
hexhash returns a hexadecimal SHA256 hash sum `string` of `s`.
Example
```v
assert sha256.hexhash('V') == 'de5a6f78116eca62d7fc5ce159d23ae6b889b365a1739ad2cf36f925a140d0cc'
```
[[Return to contents]](#Contents)
## hexhash_224
```v
fn hexhash_224(s string) string
```
hexhash_224 returns a hexadecimal SHA224 hash sum `string` of `s`.
[[Return to contents]](#Contents)
## new
```v
fn new() &Digest
```
new returns a new Digest (implementing hash.Hash) computing the SHA256 checksum.
[[Return to contents]](#Contents)
## new224
```v
fn new224() &Digest
```
new224 returns a new Digest (implementing hash.Hash) computing the SHA224 checksum.
[[Return to contents]](#Contents)
## sum
```v
fn sum(data []u8) []u8
```
sum returns the SHA256 checksum of the bytes in `data`.
Example
```v
assert sha256.sum('V'.bytes()).len > 0 == true
```
[[Return to contents]](#Contents)
## sum224
```v
fn sum224(data []u8) []u8
```
sum224 returns the SHA224 checksum of the data.
[[Return to contents]](#Contents)
## sum256
```v
fn sum256(data []u8) []u8
```
sum256 returns the SHA256 checksum of the data.
[[Return to contents]](#Contents)
## Digest
## free
```v
fn (mut d Digest) free()
```
free the resources taken by the Digest `d`
[[Return to contents]](#Contents)
## reset
```v
fn (mut d Digest) reset()
```
reset the state of the Digest `d`
[[Return to contents]](#Contents)
## write
```v
fn (mut d Digest) write(p_ []u8) !int
```
write writes the contents of `p_` to the internal hash representation.
[[Return to contents]](#Contents)
## sum
```v
fn (d &Digest) sum(b_in []u8) []u8
```
sum returns the SHA256 or SHA224 checksum of digest with the data.
[[Return to contents]](#Contents)
## size
```v
fn (d &Digest) size() int
```
size returns the size of the checksum in bytes.
[[Return to contents]](#Contents)
## block_size
```v
fn (d &Digest) block_size() int
```
block_size returns the block size of the checksum in bytes.
[[Return to contents]](#Contents)
#### Powered by vdoc. Generated on: 2 Sep 2025 07:18:17

View File

@@ -0,0 +1,327 @@
# module sha3
## Contents
- [Constants](#Constants)
- [keccak256](#keccak256)
- [keccak512](#keccak512)
- [new128xof](#new128xof)
- [new224](#new224)
- [new256](#new256)
- [new256keccak](#new256keccak)
- [new256xof](#new256xof)
- [new384](#new384)
- [new512](#new512)
- [new512keccak](#new512keccak)
- [new_digest](#new_digest)
- [new_xof_digest](#new_xof_digest)
- [shake128](#shake128)
- [shake256](#shake256)
- [sum224](#sum224)
- [sum256](#sum256)
- [sum384](#sum384)
- [sum512](#sum512)
- [Digest](#Digest)
- [write](#write)
- [checksum](#checksum)
- [Padding](#Padding)
- [PaddingConfig](#PaddingConfig)
## Constants
```v
const size_224 = 28
```
size_224 is the size, in bytes, of a sha3 sum224 checksum.
[[Return to contents]](#Contents)
```v
const size_256 = 32
```
size_256 is the size, in bytes, of a sha3 sum256 checksum.
[[Return to contents]](#Contents)
```v
const size_384 = 48
```
size_384 is the size, in bytes, of a sha3 sum384 checksum.
[[Return to contents]](#Contents)
```v
const size_512 = 64
```
size_512 is the size, in bytes, of a sha3 sum512 checksum.
[[Return to contents]](#Contents)
```v
const rate_224 = 144
```
rate_224 is the rate, in bytes, absorbed into the sponge on every permutation
[[Return to contents]](#Contents)
```v
const rate_256 = 136
```
rate_256 is the rate, in bytes, absorbed into the sponge on every permutation
[[Return to contents]](#Contents)
```v
const rate_384 = 104
```
rate_384 is the rate, in bytes, absorbed into the sponge on every permutation
[[Return to contents]](#Contents)
```v
const rate_512 = 72
```
rate_512 is the rate, in bytes, absorbed into the sponge on every permutation
[[Return to contents]](#Contents)
```v
const xof_rate_128 = 168
```
xof_rate_128 is the capacity, in bytes, of a 128 bit extended output function sponge
[[Return to contents]](#Contents)
```v
const xof_rate_256 = 136
```
xof_rate_256 is the capacity, in bytes, of a 256 bit extended output function sponge
[[Return to contents]](#Contents)
## keccak256
```v
fn keccak256(data []u8) []u8
```
keccak256 returns the keccak 256 bit checksum of the data.
[[Return to contents]](#Contents)
## keccak512
```v
fn keccak512(data []u8) []u8
```
keccak512 returns the keccak 512 bit checksum of the data.
[[Return to contents]](#Contents)
## new128xof
```v
fn new128xof(output_len int) !&Digest
```
new128_xof initializes the digest structure for a sha3 128 bit extended output function
[[Return to contents]](#Contents)
## new224
```v
fn new224() !&Digest
```
new224 initializes the digest structure for a sha3 224 bit hash
[[Return to contents]](#Contents)
## new256
```v
fn new256() !&Digest
```
new256 initializes the digest structure for a sha3 256 bit hash
[[Return to contents]](#Contents)
## new256keccak
```v
fn new256keccak() !&Digest
```
new256keccak initializes the digest structure for a keccak 256 bit hash
[[Return to contents]](#Contents)
## new256xof
```v
fn new256xof(output_len int) !&Digest
```
new256_xof initializes the digest structure for a sha3 256 bit extended output function
[[Return to contents]](#Contents)
## new384
```v
fn new384() !&Digest
```
new384 initializes the digest structure for a sha3 384 bit hash
[[Return to contents]](#Contents)
## new512
```v
fn new512() !&Digest
```
new512 initializes the digest structure for a sha3 512 bit hash
[[Return to contents]](#Contents)
## new512keccak
```v
fn new512keccak() !&Digest
```
new512keccak initializes the digest structure for a keccak 512 bit hash
[[Return to contents]](#Contents)
## new_digest
```v
fn new_digest(absorption_rate int, hash_size int, config PaddingConfig) !&Digest
```
new_digest creates an initialized digest structure based on the hash size.
absorption_rate is the number of bytes to be absorbed into the sponge per permutation.
hash_size - the number if bytes in the generated hash. Legal values are 224, 256, 384, and 512.
config - the padding setting for hash generation. .sha3 should be used for FIPS PUB 202 compliant SHA3-224, SHA3-256, SHA3-384 and SHA3-512. Use .keccak if you want a legacy Keccak-224, Keccak-256, Keccak-384 or Keccak-512 algorithm. .xof is for extended output functions.
[[Return to contents]](#Contents)
## new_xof_digest
```v
fn new_xof_digest(absorption_rate int, hash_size int) !&Digest
```
new_xof_digest creates an initialized digest structure based on the absorption rate and how many bytes of output you need
absorption_rate is the number of bytes to be absorbed into the sponge per permutation. Legal values are xof_rate_128 and xof_rate_256.
hash_size - the number if bytes in the generated hash. Legal values are positive integers.
[[Return to contents]](#Contents)
## shake128
```v
fn shake128(data []u8, output_len int) []u8
```
shake128 returns the sha3 shake128 bit extended output
[[Return to contents]](#Contents)
## shake256
```v
fn shake256(data []u8, output_len int) []u8
```
shake256 returns the sha3 shake256 bit extended output
[[Return to contents]](#Contents)
## sum224
```v
fn sum224(data []u8) []u8
```
sum224 returns the sha3 224 bit checksum of the data.
[[Return to contents]](#Contents)
## sum256
```v
fn sum256(data []u8) []u8
```
sum256 returns the sha3 256 bit checksum of the data.
[[Return to contents]](#Contents)
## sum384
```v
fn sum384(data []u8) []u8
```
sum384 returns the sha3 384 bit checksum of the data.
[[Return to contents]](#Contents)
## sum512
```v
fn sum512(data []u8) []u8
```
sum512 returns the sha3 512 bit checksum of the data.
[[Return to contents]](#Contents)
## Digest
## write
```v
fn (mut d Digest) write(data []u8) !
```
write adds bytes to the sponge.
This is the absorption phase of the computation.
[[Return to contents]](#Contents)
## checksum
```v
fn (mut d Digest) checksum() []u8
```
checksum finalizes the hash and returns the generated bytes.
[[Return to contents]](#Contents)
## Padding
```v
enum Padding as u8 {
keccak = 0x01
sha3 = 0x06
xof = 0x1f
}
```
the low order pad bits for a hash function
[[Return to contents]](#Contents)
## PaddingConfig
```v
struct PaddingConfig {
pub:
padding Padding = .sha3
}
```
[[Return to contents]](#Contents)
#### Powered by vdoc. Generated on: 2 Sep 2025 07:18:17

View File

@@ -0,0 +1,230 @@
# module sha512
## Contents
- [Constants](#Constants)
- [hexhash](#hexhash)
- [hexhash_384](#hexhash_384)
- [hexhash_512_224](#hexhash_512_224)
- [hexhash_512_256](#hexhash_512_256)
- [new](#new)
- [new384](#new384)
- [new512_224](#new512_224)
- [new512_256](#new512_256)
- [sum384](#sum384)
- [sum512](#sum512)
- [sum512_224](#sum512_224)
- [sum512_256](#sum512_256)
- [Digest](#Digest)
- [free](#free)
- [reset](#reset)
- [write](#write)
- [sum](#sum)
- [size](#size)
- [block_size](#block_size)
## Constants
```v
const size = 64
```
size is the size, in bytes, of a SHA-512 checksum.
[[Return to contents]](#Contents)
```v
const size224 = 28
```
size224 is the size, in bytes, of a SHA-512/224 checksum.
[[Return to contents]](#Contents)
```v
const size256 = 32
```
size256 is the size, in bytes, of a SHA-512/256 checksum.
[[Return to contents]](#Contents)
```v
const size384 = 48
```
size384 is the size, in bytes, of a SHA-384 checksum.
[[Return to contents]](#Contents)
```v
const block_size = 128
```
block_size is the block size, in bytes, of the SHA-512/224, SHA-512/256, SHA-384 and SHA-512 hash functions.
[[Return to contents]](#Contents)
## hexhash
```v
fn hexhash(s string) string
```
hexhash returns a hexadecimal SHA512 hash sum `string` of `s`.
[[Return to contents]](#Contents)
## hexhash_384
```v
fn hexhash_384(s string) string
```
hexhash_384 returns a hexadecimal SHA384 hash sum `string` of `s`.
[[Return to contents]](#Contents)
## hexhash_512_224
```v
fn hexhash_512_224(s string) string
```
hexhash_512_224 returns a hexadecimal SHA512/224 hash sum `string` of `s`.
[[Return to contents]](#Contents)
## hexhash_512_256
```v
fn hexhash_512_256(s string) string
```
hexhash_512_256 returns a hexadecimal 512/256 hash sum `string` of `s`.
[[Return to contents]](#Contents)
## new
```v
fn new() &Digest
```
new returns a new Digest (implementing hash.Hash) computing the SHA-512 checksum.
[[Return to contents]](#Contents)
## new384
```v
fn new384() &Digest
```
new384 returns a new Digest (implementing hash.Hash) computing the SHA-384 checksum.
[[Return to contents]](#Contents)
## new512_224
```v
fn new512_224() &Digest
```
new512_224 returns a new Digest (implementing hash.Hash) computing the SHA-512/224 checksum.
[[Return to contents]](#Contents)
## new512_256
```v
fn new512_256() &Digest
```
new512_256 returns a new Digest (implementing hash.Hash) computing the SHA-512/256 checksum.
[[Return to contents]](#Contents)
## sum384
```v
fn sum384(data []u8) []u8
```
sum384 returns the SHA384 checksum of the data.
[[Return to contents]](#Contents)
## sum512
```v
fn sum512(data []u8) []u8
```
sum512 returns the SHA512 checksum of the data.
[[Return to contents]](#Contents)
## sum512_224
```v
fn sum512_224(data []u8) []u8
```
sum512_224 returns the Sum512/224 checksum of the data.
[[Return to contents]](#Contents)
## sum512_256
```v
fn sum512_256(data []u8) []u8
```
sum512_256 returns the Sum512/256 checksum of the data.
[[Return to contents]](#Contents)
## Digest
## free
```v
fn (mut d Digest) free()
```
free the resources taken by the Digest `d`
[[Return to contents]](#Contents)
## reset
```v
fn (mut d Digest) reset()
```
reset the state of the Digest `d`
[[Return to contents]](#Contents)
## write
```v
fn (mut d Digest) write(p_ []u8) !int
```
write writes the contents of `p_` to the internal hash representation.
[[Return to contents]](#Contents)
## sum
```v
fn (d &Digest) sum(b_in []u8) []u8
```
sum returns the SHA512 or SHA384 checksum of digest with the data bytes in `b_in`
[[Return to contents]](#Contents)
## size
```v
fn (d &Digest) size() int
```
size returns the size of the checksum in bytes.
[[Return to contents]](#Contents)
## block_size
```v
fn (d &Digest) block_size() int
```
block_size returns the block size of the checksum in bytes.
[[Return to contents]](#Contents)
#### Powered by vdoc. Generated on: 2 Sep 2025 07:18:17

View File

@@ -0,0 +1,184 @@
# module base32
## Contents
- [Constants](#Constants)
- [decode](#decode)
- [decode_string_to_string](#decode_string_to_string)
- [decode_to_string](#decode_to_string)
- [encode](#encode)
- [encode_string_to_string](#encode_string_to_string)
- [encode_to_string](#encode_to_string)
- [new_encoding](#new_encoding)
- [new_encoding_with_padding](#new_encoding_with_padding)
- [new_std_encoding](#new_std_encoding)
- [new_std_encoding_with_padding](#new_std_encoding_with_padding)
- [Encoding](#Encoding)
- [encode_to_string](#encode_to_string)
- [encode_string_to_string](#encode_string_to_string)
- [decode_string](#decode_string)
- [decode_string_to_string](#decode_string_to_string)
- [decode](#decode)
## Constants
```v
const std_padding = `=` // Standard padding character
```
[[Return to contents]](#Contents)
```v
const no_padding = u8(-1) // No padding
```
[[Return to contents]](#Contents)
```v
const std_alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'.bytes()
```
[[Return to contents]](#Contents)
```v
const hex_alphabet = '0123456789ABCDEFGHIJKLMNOPQRSTUV'.bytes()
```
[[Return to contents]](#Contents)
## decode
```v
fn decode(src []u8) ![]u8
```
decode decodes a byte array `src` using Base32 and returns the decoded bytes or a `corrupt_input_error_msg` error.
[[Return to contents]](#Contents)
## decode_string_to_string
```v
fn decode_string_to_string(src string) !string
```
decode_string_to_string decodes a V string `src` using Base32 and returns the decoded string or a `corrupt_input_error_msg` error.
[[Return to contents]](#Contents)
## decode_to_string
```v
fn decode_to_string(src []u8) !string
```
decode_to_string decodes a byte array `src` using Base32 and returns the decoded string or a `corrupt_input_error_msg` error.
[[Return to contents]](#Contents)
## encode
```v
fn encode(src []u8) []u8
```
encode encodes a byte array `src` using Base32 and returns the encoded bytes.
[[Return to contents]](#Contents)
## encode_string_to_string
```v
fn encode_string_to_string(src string) string
```
encode_string_to_string encodes the V string `src` using Base32 and returns the encoded bytes as a V string.
[[Return to contents]](#Contents)
## encode_to_string
```v
fn encode_to_string(src []u8) string
```
encode_to_string encodes a byte array `src` using Base32 and returns the encoded bytes as a V string.
[[Return to contents]](#Contents)
## new_encoding
```v
fn new_encoding(alphabet []u8) Encoding
```
new_encoding returns a Base32 `Encoding` with standard `alphabet`s and standard padding.
[[Return to contents]](#Contents)
## new_encoding_with_padding
```v
fn new_encoding_with_padding(alphabet []u8, padding_char u8) Encoding
```
new_encoding_with_padding returns a Base32 `Encoding` with specified encoding `alphabet`s and a specified `padding_char`. The `padding_char` must not be '\r' or '\n', must not be contained in the `Encoding`'s alphabet and must be a rune equal or below '\xff'.
[[Return to contents]](#Contents)
## new_std_encoding
```v
fn new_std_encoding() Encoding
```
new_std_encoding creates a standard Base32 `Encoding` as defined in RFC 4648.
[[Return to contents]](#Contents)
## new_std_encoding_with_padding
```v
fn new_std_encoding_with_padding(padding u8) Encoding
```
new_std_encoding creates a standard Base32 `Encoding` identical to `new_std_encoding` but with a specified character `padding`, or `no_padding` to disable padding. The `padding` character must not be '\r' or '\n', must not be contained in the `Encoding`'s alphabet and must be a rune equal or below '\xff'.
[[Return to contents]](#Contents)
## Encoding
## encode_to_string
```v
fn (enc &Encoding) encode_to_string(src []u8) string
```
encode_to_string encodes the Base32 encoding of `src` with the encoding `enc` and returns the encoded bytes as a V string.
[[Return to contents]](#Contents)
## encode_string_to_string
```v
fn (enc &Encoding) encode_string_to_string(src string) string
```
encode_string_to_string encodes a V string `src` using Base32 with the encoding `enc` and returns the encoded bytes as a V string.
[[Return to contents]](#Contents)
## decode_string
```v
fn (enc &Encoding) decode_string(src string) ![]u8
```
decode_string decodes a V string `src` using Base32 with the encoding `enc` and returns the decoded bytes or a `corrupt_input_error_msg` error.
[[Return to contents]](#Contents)
## decode_string_to_string
```v
fn (enc &Encoding) decode_string_to_string(src string) !string
```
decode_string_to_string decodes a V string `src` using Base32 with the encoding `enc` and returns the decoded V string or a `corrupt_input_error_msg` error.
[[Return to contents]](#Contents)
## decode
```v
fn (enc &Encoding) decode(src []u8) ![]u8
```
decode decodes `src` using the encoding `enc`. It returns the decoded bytes written or a `corrupt_input_error_msg` error. New line characters (\r and \n) are ignored.
[[Return to contents]](#Contents)
#### Powered by vdoc. Generated on: 2 Sep 2025 07:18:04

View File

@@ -0,0 +1,186 @@
# module base58
## Contents
- [Constants](#Constants)
- [decode](#decode)
- [decode_bytes](#decode_bytes)
- [decode_int](#decode_int)
- [decode_int_walpha](#decode_int_walpha)
- [decode_walpha](#decode_walpha)
- [decode_walpha_bytes](#decode_walpha_bytes)
- [encode](#encode)
- [encode_bytes](#encode_bytes)
- [encode_int](#encode_int)
- [encode_int_walpha](#encode_int_walpha)
- [encode_walpha](#encode_walpha)
- [encode_walpha_bytes](#encode_walpha_bytes)
- [new_alphabet](#new_alphabet)
- [Alphabet](#Alphabet)
- [str](#str)
## Constants
```v
const btc_alphabet = new_alphabet('123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz') or {
panic(impossible)
}
```
[[Return to contents]](#Contents)
```v
const flickr_alphabet = new_alphabet('123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ') or {
panic(impossible)
}
```
[[Return to contents]](#Contents)
```v
const ripple_alphabet = new_alphabet('rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz') or {
panic(impossible)
}
```
[[Return to contents]](#Contents)
```v
const alphabets = {
'btc': btc_alphabet
'flickr': flickr_alphabet
'ripple': ripple_alphabet
}
```
alphabets is a map of common base58 alphabets:
[[Return to contents]](#Contents)
## decode
```v
fn decode(str string) !string
```
decode decodes the base58 input string, using the Bitcoin alphabet
[[Return to contents]](#Contents)
## decode_bytes
```v
fn decode_bytes(input []u8) ![]u8
```
decode_bytes decodes the base58 encoded input array, using the Bitcoin alphabet
[[Return to contents]](#Contents)
## decode_int
```v
fn decode_int(input string) !int
```
decode_int decodes base58 string to an integer with Bitcoin alphabet
[[Return to contents]](#Contents)
## decode_int_walpha
```v
fn decode_int_walpha(input string, alphabet Alphabet) !int
```
decode_int_walpha decodes base58 string to an integer with custom alphabet
[[Return to contents]](#Contents)
## decode_walpha
```v
fn decode_walpha(input string, alphabet Alphabet) !string
```
decode_walpha decodes the base58 encoded input string, using custom alphabet
[[Return to contents]](#Contents)
## decode_walpha_bytes
```v
fn decode_walpha_bytes(input []u8, alphabet Alphabet) ![]u8
```
decode_walpha_bytes decodes the base58 encoded input array using a custom alphabet
[[Return to contents]](#Contents)
## encode
```v
fn encode(input string) string
```
encode encodes the input string to base58 with the Bitcoin alphabet
[[Return to contents]](#Contents)
## encode_bytes
```v
fn encode_bytes(input []u8) []u8
```
encode_bytes encodes the input array to base58, with the Bitcoin alphabet
[[Return to contents]](#Contents)
## encode_int
```v
fn encode_int(input int) !string
```
encode_int encodes any integer type to base58 string with Bitcoin alphabet
[[Return to contents]](#Contents)
## encode_int_walpha
```v
fn encode_int_walpha(input int, alphabet Alphabet) !string
```
encode_int_walpha any integer type to base58 string with custom alphabet
[[Return to contents]](#Contents)
## encode_walpha
```v
fn encode_walpha(input string, alphabet Alphabet) string
```
encode_walpha encodes the input string to base58 with a custom aplhabet
[[Return to contents]](#Contents)
## encode_walpha_bytes
```v
fn encode_walpha_bytes(input []u8, alphabet Alphabet) []u8
```
encode_walpha encodes the input array to base58 with a custom aplhabet
[[Return to contents]](#Contents)
## new_alphabet
```v
fn new_alphabet(str string) !Alphabet
```
new_alphabet instantiates an Alphabet object based on the provided characters
[[Return to contents]](#Contents)
## Alphabet
## str
```v
fn (alphabet Alphabet) str() string
```
str returns an Alphabet encode table byte array as a string
[[Return to contents]](#Contents)
#### Powered by vdoc. Generated on: 2 Sep 2025 07:18:04

Some files were not shown because too many files have changed in this diff Show More