Compare commits
2 commits
pragmatism
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| aaba2976b4 | |||
| 116f11cb42 |
29 changed files with 620 additions and 1717 deletions
12
.gitignore
vendored
12
.gitignore
vendored
|
|
@ -30,17 +30,7 @@ botserver-installers/*
|
||||||
!botserver-installers/.gitkeep
|
!botserver-installers/.gitkeep
|
||||||
botserver-stack
|
botserver-stack
|
||||||
TODO*
|
TODO*
|
||||||
work
|
|
||||||
|
|
||||||
# Lock file (regenerated from Cargo.toml)
|
# Lock file (regenerated from Cargo.toml)
|
||||||
Cargo.lock
|
Cargo.lock
|
||||||
.kiro
|
|
||||||
config
|
|
||||||
|
|
||||||
# Playwright
|
|
||||||
node_modules/
|
|
||||||
/test-results/
|
|
||||||
/playwright-report/
|
|
||||||
/blob-report/
|
|
||||||
/playwright/.cache/
|
|
||||||
/playwright/.auth/
|
|
||||||
|
|
|
||||||
22
.gitmodules
vendored
22
.gitmodules
vendored
|
|
@ -1,42 +1,42 @@
|
||||||
[submodule "botapp"]
|
[submodule "botapp"]
|
||||||
path = botapp
|
path = botapp
|
||||||
url = https://alm.pragmatismo.com.br/GeneralBots/botapp.git
|
url = https://github.com/GeneralBots/botapp.git
|
||||||
|
|
||||||
[submodule "botserver"]
|
[submodule "botserver"]
|
||||||
path = botserver
|
path = botserver
|
||||||
url = https://alm.pragmatismo.com.br/GeneralBots/botserver.git
|
url = https://github.com/GeneralBots/botserver.git
|
||||||
|
|
||||||
[submodule "botlib"]
|
[submodule "botlib"]
|
||||||
path = botlib
|
path = botlib
|
||||||
url = https://alm.pragmatismo.com.br/GeneralBots/botlib.git
|
url = https://github.com/GeneralBots/botlib.git
|
||||||
|
|
||||||
[submodule "botui"]
|
[submodule "botui"]
|
||||||
path = botui
|
path = botui
|
||||||
url = https://alm.pragmatismo.com.br/GeneralBots/botui.git
|
url = https://github.com/GeneralBots/botui.git
|
||||||
|
|
||||||
[submodule "botbook"]
|
[submodule "botbook"]
|
||||||
path = botbook
|
path = botbook
|
||||||
url = https://alm.pragmatismo.com.br/GeneralBots/botbook.git
|
url = https://github.com/GeneralBots/botbook.git
|
||||||
|
|
||||||
[submodule "bottest"]
|
[submodule "bottest"]
|
||||||
path = bottest
|
path = bottest
|
||||||
url = https://alm.pragmatismo.com.br/GeneralBots/bottest.git
|
url = https://github.com/GeneralBots/bottest.git
|
||||||
|
|
||||||
[submodule "botdevice"]
|
[submodule "botdevice"]
|
||||||
path = botdevice
|
path = botdevice
|
||||||
url = https://alm.pragmatismo.com.br/GeneralBots/botdevice.git
|
url = https://github.com/GeneralBots/botdevice.git
|
||||||
|
|
||||||
[submodule "botmodels"]
|
[submodule "botmodels"]
|
||||||
path = botmodels
|
path = botmodels
|
||||||
url = https://alm.pragmatismo.com.br/GeneralBots/botmodels.git
|
url = https://github.com/GeneralBots/botmodels.git
|
||||||
|
|
||||||
[submodule "botplugin"]
|
[submodule "botplugin"]
|
||||||
path = botplugin
|
path = botplugin
|
||||||
url = https://alm.pragmatismo.com.br/GeneralBots/botplugin.git
|
url = https://github.com/GeneralBots/botplugin.git
|
||||||
|
|
||||||
[submodule "bottemplates"]
|
[submodule "bottemplates"]
|
||||||
path = bottemplates
|
path = bottemplates
|
||||||
url = https://alm.pragmatismo.com.br/GeneralBots/bottemplates.git
|
url = https://github.com/GeneralBots/bottemplates.git
|
||||||
[submodule ".github"]
|
[submodule ".github"]
|
||||||
path = .github
|
path = .github
|
||||||
url = https://alm.pragmatismo.com.br/GeneralBots/.github.git
|
url = https://github.com/GeneralBots/.github.git
|
||||||
|
|
|
||||||
9
.idea/gb.iml
generated
9
.idea/gb.iml
generated
|
|
@ -1,9 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<module type="JAVA_MODULE" version="4">
|
|
||||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
|
||||||
<exclude-output />
|
|
||||||
<content url="file://$MODULE_DIR$" />
|
|
||||||
<orderEntry type="inheritedJdk" />
|
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
|
||||||
</component>
|
|
||||||
</module>
|
|
||||||
10
.idea/libraries/botserver_installers.xml
generated
10
.idea/libraries/botserver_installers.xml
generated
|
|
@ -1,10 +0,0 @@
|
||||||
<component name="libraryTable">
|
|
||||||
<library name="botserver-installers">
|
|
||||||
<CLASSES>
|
|
||||||
<root url="jar://$PROJECT_DIR$/botserver/botserver-installers/llama-b7345-bin-ubuntu-x64.zip!/" />
|
|
||||||
<root url="jar://$PROJECT_DIR$/botserver/botserver-installers/vault_1.15.4_linux_amd64.zip!/" />
|
|
||||||
</CLASSES>
|
|
||||||
<JAVADOC />
|
|
||||||
<SOURCES />
|
|
||||||
</library>
|
|
||||||
</component>
|
|
||||||
6
.idea/misc.xml
generated
6
.idea/misc.xml
generated
|
|
@ -1,6 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="ProjectRootManager" version="2">
|
|
||||||
<output url="file://$PROJECT_DIR$/out" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
8
.idea/modules.xml
generated
8
.idea/modules.xml
generated
|
|
@ -1,8 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="ProjectModuleManager">
|
|
||||||
<modules>
|
|
||||||
<module fileurl="file://$PROJECT_DIR$/.idea/gb.iml" filepath="$PROJECT_DIR$/.idea/gb.iml" />
|
|
||||||
</modules>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
6
.idea/vcs.xml
generated
6
.idea/vcs.xml
generated
|
|
@ -1,6 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="VcsDirectoryMappings">
|
|
||||||
<mapping directory="" vcs="Git" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
52
.idea/workspace.xml
generated
52
.idea/workspace.xml
generated
|
|
@ -1,52 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="ChangeListManager">
|
|
||||||
<list default="true" id="32fd08b0-7933-467d-9a46-1a53fd2da15c" name="Changes" comment="">
|
|
||||||
<change beforePath="$PROJECT_DIR$/botserver" beforeDir="false" afterPath="$PROJECT_DIR$/botserver" afterDir="false" />
|
|
||||||
</list>
|
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
|
||||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
|
||||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
|
||||||
</component>
|
|
||||||
<component name="Git.Settings">
|
|
||||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
|
||||||
</component>
|
|
||||||
<component name="ProjectColorInfo"><![CDATA[{
|
|
||||||
"associatedIndex": 1
|
|
||||||
}]]></component>
|
|
||||||
<component name="ProjectId" id="38qdWTFkX8Nem4LzgigXpAycSN7" />
|
|
||||||
<component name="ProjectViewState">
|
|
||||||
<option name="hideEmptyMiddlePackages" value="true" />
|
|
||||||
<option name="showLibraryContents" value="true" />
|
|
||||||
</component>
|
|
||||||
<component name="PropertiesComponent"><![CDATA[{
|
|
||||||
"keyToString": {
|
|
||||||
"ModuleVcsDetector.initialDetectionPerformed": "true",
|
|
||||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
|
||||||
"RunOnceActivity.git.unshallow": "true",
|
|
||||||
"RunOnceActivity.typescript.service.memoryLimit.init": "true",
|
|
||||||
"git-widget-placeholder": "main",
|
|
||||||
"last_opened_file_path": "/home/rodriguez/src/gb",
|
|
||||||
"vue.rearranger.settings.migration": "true"
|
|
||||||
}
|
|
||||||
}]]></component>
|
|
||||||
<component name="SharedIndexes">
|
|
||||||
<attachedChunks>
|
|
||||||
<set>
|
|
||||||
<option value="bundled-jdk-30f59d01ecdd-2fc7cc6b9a17-intellij.indexing.shared.core-IU-253.30387.90" />
|
|
||||||
</set>
|
|
||||||
</attachedChunks>
|
|
||||||
</component>
|
|
||||||
<component name="TaskManager">
|
|
||||||
<task active="true" id="Default" summary="Default task">
|
|
||||||
<changelist id="32fd08b0-7933-467d-9a46-1a53fd2da15c" name="Changes" comment="" />
|
|
||||||
<created>1769531070022</created>
|
|
||||||
<option name="number" value="Default" />
|
|
||||||
<option name="presentableId" value="Default" />
|
|
||||||
<updated>1769531070022</updated>
|
|
||||||
<workItem from="1769531115917" duration="176000" />
|
|
||||||
</task>
|
|
||||||
<servers />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
|
|
@ -1,198 +0,0 @@
|
||||||
{
|
|
||||||
"languages": {
|
|
||||||
"typescript": {
|
|
||||||
"name": "typescript-language-server",
|
|
||||||
"command": "typescript-language-server",
|
|
||||||
"args": [
|
|
||||||
"--stdio"
|
|
||||||
],
|
|
||||||
"file_extensions": [
|
|
||||||
"ts",
|
|
||||||
"js",
|
|
||||||
"tsx",
|
|
||||||
"jsx"
|
|
||||||
],
|
|
||||||
"project_patterns": [
|
|
||||||
"package.json",
|
|
||||||
"tsconfig.json"
|
|
||||||
],
|
|
||||||
"exclude_patterns": [
|
|
||||||
"**/node_modules/**",
|
|
||||||
"**/dist/**"
|
|
||||||
],
|
|
||||||
"multi_workspace": false,
|
|
||||||
"initialization_options": {
|
|
||||||
"preferences": {
|
|
||||||
"disableSuggestions": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"request_timeout_secs": 60
|
|
||||||
},
|
|
||||||
"python": {
|
|
||||||
"name": "pyright",
|
|
||||||
"command": "pyright-langserver",
|
|
||||||
"args": [
|
|
||||||
"--stdio"
|
|
||||||
],
|
|
||||||
"file_extensions": [
|
|
||||||
"py"
|
|
||||||
],
|
|
||||||
"project_patterns": [
|
|
||||||
"pyproject.toml",
|
|
||||||
"setup.py",
|
|
||||||
"requirements.txt",
|
|
||||||
"pyrightconfig.json"
|
|
||||||
],
|
|
||||||
"exclude_patterns": [
|
|
||||||
"**/__pycache__/**",
|
|
||||||
"**/venv/**",
|
|
||||||
"**/.venv/**",
|
|
||||||
"**/.pytest_cache/**"
|
|
||||||
],
|
|
||||||
"multi_workspace": false,
|
|
||||||
"initialization_options": {},
|
|
||||||
"request_timeout_secs": 60
|
|
||||||
},
|
|
||||||
"rust": {
|
|
||||||
"name": "rust-analyzer",
|
|
||||||
"command": "rust-analyzer",
|
|
||||||
"args": [],
|
|
||||||
"file_extensions": [
|
|
||||||
"rs"
|
|
||||||
],
|
|
||||||
"project_patterns": [
|
|
||||||
"Cargo.toml"
|
|
||||||
],
|
|
||||||
"exclude_patterns": [
|
|
||||||
"**/target/**"
|
|
||||||
],
|
|
||||||
"multi_workspace": false,
|
|
||||||
"initialization_options": {
|
|
||||||
"cargo": {
|
|
||||||
"buildScripts": {
|
|
||||||
"enable": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"diagnostics": {
|
|
||||||
"enable": true,
|
|
||||||
"enableExperimental": true
|
|
||||||
},
|
|
||||||
"workspace": {
|
|
||||||
"symbol": {
|
|
||||||
"search": {
|
|
||||||
"scope": "workspace"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"request_timeout_secs": 60
|
|
||||||
},
|
|
||||||
"java": {
|
|
||||||
"name": "jdtls",
|
|
||||||
"command": "jdtls",
|
|
||||||
"args": [],
|
|
||||||
"file_extensions": [
|
|
||||||
"java"
|
|
||||||
],
|
|
||||||
"project_patterns": [
|
|
||||||
"pom.xml",
|
|
||||||
"build.gradle",
|
|
||||||
"build.gradle.kts",
|
|
||||||
".project"
|
|
||||||
],
|
|
||||||
"exclude_patterns": [
|
|
||||||
"**/target/**",
|
|
||||||
"**/build/**",
|
|
||||||
"**/.gradle/**"
|
|
||||||
],
|
|
||||||
"multi_workspace": false,
|
|
||||||
"initialization_options": {
|
|
||||||
"settings": {
|
|
||||||
"java": {
|
|
||||||
"compile": {
|
|
||||||
"nullAnalysis": {
|
|
||||||
"mode": "automatic"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"configuration": {
|
|
||||||
"annotationProcessing": {
|
|
||||||
"enabled": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"request_timeout_secs": 60
|
|
||||||
},
|
|
||||||
"ruby": {
|
|
||||||
"name": "solargraph",
|
|
||||||
"command": "solargraph",
|
|
||||||
"args": [
|
|
||||||
"stdio"
|
|
||||||
],
|
|
||||||
"file_extensions": [
|
|
||||||
"rb"
|
|
||||||
],
|
|
||||||
"project_patterns": [
|
|
||||||
"Gemfile",
|
|
||||||
"Rakefile"
|
|
||||||
],
|
|
||||||
"exclude_patterns": [
|
|
||||||
"**/vendor/**",
|
|
||||||
"**/tmp/**"
|
|
||||||
],
|
|
||||||
"multi_workspace": false,
|
|
||||||
"initialization_options": {},
|
|
||||||
"request_timeout_secs": 60
|
|
||||||
},
|
|
||||||
"go": {
|
|
||||||
"name": "gopls",
|
|
||||||
"command": "gopls",
|
|
||||||
"args": [],
|
|
||||||
"file_extensions": [
|
|
||||||
"go"
|
|
||||||
],
|
|
||||||
"project_patterns": [
|
|
||||||
"go.mod",
|
|
||||||
"go.sum"
|
|
||||||
],
|
|
||||||
"exclude_patterns": [
|
|
||||||
"**/vendor/**"
|
|
||||||
],
|
|
||||||
"multi_workspace": false,
|
|
||||||
"initialization_options": {
|
|
||||||
"usePlaceholders": true,
|
|
||||||
"completeUnimported": true
|
|
||||||
},
|
|
||||||
"request_timeout_secs": 60
|
|
||||||
},
|
|
||||||
"cpp": {
|
|
||||||
"name": "clangd",
|
|
||||||
"command": "clangd",
|
|
||||||
"args": [
|
|
||||||
"--background-index"
|
|
||||||
],
|
|
||||||
"file_extensions": [
|
|
||||||
"cpp",
|
|
||||||
"cc",
|
|
||||||
"cxx",
|
|
||||||
"c",
|
|
||||||
"h",
|
|
||||||
"hpp",
|
|
||||||
"hxx"
|
|
||||||
],
|
|
||||||
"project_patterns": [
|
|
||||||
"CMakeLists.txt",
|
|
||||||
"compile_commands.json",
|
|
||||||
"Makefile"
|
|
||||||
],
|
|
||||||
"exclude_patterns": [
|
|
||||||
"**/build/**",
|
|
||||||
"**/cmake-build-**/**"
|
|
||||||
],
|
|
||||||
"multi_workspace": false,
|
|
||||||
"initialization_options": {},
|
|
||||||
"request_timeout_secs": 60
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
{
|
|
||||||
"languages": {
|
|
||||||
"Rust": {
|
|
||||||
"enable_language_server": false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
@ -38,7 +38,7 @@
|
||||||
echo -e "${YELLOW}OS: $OS${NC}"
|
echo -e "${YELLOW}OS: $OS${NC}"
|
||||||
|
|
||||||
install_debian_ubuntu() {
|
install_debian_ubuntu() {
|
||||||
|
apt-get update
|
||||||
apt-get install -y \
|
apt-get install -y \
|
||||||
libpq5 \
|
libpq5 \
|
||||||
libssl3 \
|
libssl3 \
|
||||||
|
|
@ -47,11 +47,18 @@
|
||||||
ca-certificates \
|
ca-certificates \
|
||||||
curl \
|
curl \
|
||||||
wget \
|
wget \
|
||||||
|
libabseil20210324 \
|
||||||
libclang1 \
|
libclang1 \
|
||||||
pkg-config \
|
pkg-config \
|
||||||
snapd
|
snapd
|
||||||
|
|
||||||
|
# LXC for containers
|
||||||
|
snap install lxd || apt-get install -y lxd || true
|
||||||
|
|
||||||
|
# Initialize LXD
|
||||||
|
if command -v lxd &> /dev/null && ! lxc list &> /dev/null 2>&1; then
|
||||||
|
lxd init --auto || true
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
install_fedora_rhel() {
|
install_fedora_rhel() {
|
||||||
|
|
|
||||||
383
PROMPT.md
Normal file
383
PROMPT.md
Normal file
|
|
@ -0,0 +1,383 @@
|
||||||
|
# General Bots Workspace - Master Development Guide
|
||||||
|
|
||||||
|
**Version:** 6.2.0 - DO NOT CHANGE
|
||||||
|
**Project:** General Bots Workspace (Rust Monorepo)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📁 WORKSPACE STRUCTURE
|
||||||
|
|
||||||
|
| Crate | Purpose | Port | Tech Stack |
|
||||||
|
|-------|---------|------|------------|
|
||||||
|
| **botserver** | Main API server, business logic | 8088 | Axum, Diesel, Rhai BASIC |
|
||||||
|
| **botui** | Web UI server (dev) + proxy | 3000 | Axum, HTML/HTMX/CSS |
|
||||||
|
| **botapp** | Desktop app wrapper | - | Tauri 2 |
|
||||||
|
| **botlib** | Shared library | - | Core types, errors |
|
||||||
|
| **botbook** | Documentation | - | mdBook |
|
||||||
|
| **bottest** | Integration tests | - | tokio-test |
|
||||||
|
| **botdevice** | IoT/Device support | - | Rust |
|
||||||
|
| **botmodels** | Data models visualization | - | - |
|
||||||
|
| **botplugin** | Browser extension | - | JS |
|
||||||
|
|
||||||
|
### Key Paths
|
||||||
|
- **Binary:** `target/debug/botserver`
|
||||||
|
- **Run from:** `botserver/` directory
|
||||||
|
- **Env file:** `botserver/.env`
|
||||||
|
- **Stack:** `botserver/botserver-stack/`
|
||||||
|
- **UI Files:** `botui/ui/suite/`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔥 ERROR FIXING WORKFLOW
|
||||||
|
|
||||||
|
### Mode 1: OFFLINE Batch Fix (PREFERRED)
|
||||||
|
|
||||||
|
When given error output:
|
||||||
|
|
||||||
|
```
|
||||||
|
1. Read ENTIRE error list first
|
||||||
|
2. Group errors by file
|
||||||
|
3. For EACH file with errors:
|
||||||
|
a. View file → understand context
|
||||||
|
b. Fix ALL errors in that file
|
||||||
|
c. Write once with all fixes
|
||||||
|
4. Move to next file
|
||||||
|
5. REPEAT until ALL errors addressed
|
||||||
|
6. ONLY THEN → verify with build/diagnostics
|
||||||
|
```
|
||||||
|
|
||||||
|
**NEVER run cargo build/check/clippy DURING fixing**
|
||||||
|
**Fix ALL errors OFFLINE first, verify ONCE at the end**
|
||||||
|
|
||||||
|
### Mode 2: Interactive Loop
|
||||||
|
|
||||||
|
```
|
||||||
|
LOOP UNTIL (0 warnings AND 0 errors):
|
||||||
|
1. Run diagnostics → pick file with issues
|
||||||
|
2. Read entire file
|
||||||
|
3. Fix ALL issues in that file
|
||||||
|
4. Write file once with all fixes
|
||||||
|
5. Verify with diagnostics
|
||||||
|
6. CONTINUE LOOP
|
||||||
|
END LOOP
|
||||||
|
```
|
||||||
|
|
||||||
|
### Common Error Patterns
|
||||||
|
|
||||||
|
| Error | Fix |
|
||||||
|
|-------|-----|
|
||||||
|
| `expected i64, found u64` | `value as i64` |
|
||||||
|
| `expected Option<T>, found T` | `Some(value)` |
|
||||||
|
| `expected T, found Option<T>` | `value.unwrap_or(default)` |
|
||||||
|
| `cannot multiply f32 by f64` | `f64::from(f32_val) * f64_val` |
|
||||||
|
| `no field X on type Y` | Check struct definition |
|
||||||
|
| `no variant X found` | Check enum definition |
|
||||||
|
| `function takes N arguments` | Match function signature |
|
||||||
|
| `cannot find function` | Add missing function or fix import |
|
||||||
|
| `unused variable` | Delete or use with `..` in patterns |
|
||||||
|
| `unused import` | Delete the import line |
|
||||||
|
| `cannot move out of X because borrowed` | Use scoping `{ }` to limit borrow |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧠 MEMORY MANAGEMENT
|
||||||
|
|
||||||
|
When compilation fails due to memory issues (process "Killed"):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pkill -9 cargo; pkill -9 rustc; pkill -9 botserver
|
||||||
|
CARGO_BUILD_JOBS=1 cargo check -p botserver 2>&1 | tail -200
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📏 FILE SIZE LIMITS - MANDATORY
|
||||||
|
|
||||||
|
### Maximum 1000 Lines Per File
|
||||||
|
|
||||||
|
When a file grows beyond this limit:
|
||||||
|
|
||||||
|
1. **Identify logical groups** - Find related functions
|
||||||
|
2. **Create subdirectory module** - e.g., `handlers/`
|
||||||
|
3. **Split by responsibility:**
|
||||||
|
- `crud.rs` - Create, Read, Update, Delete
|
||||||
|
- `ai.rs` - AI/ML handlers
|
||||||
|
- `export.rs` - Export/import
|
||||||
|
- `validation.rs` - Validation
|
||||||
|
- `mod.rs` - Re-exports
|
||||||
|
4. **Keep files focused** - Single responsibility
|
||||||
|
5. **Update mod.rs** - Re-export all public items
|
||||||
|
|
||||||
|
**NEVER let a single file exceed 1000 lines - split proactively at 800 lines**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 PERFORMANCE & SIZE STANDARDS
|
||||||
|
|
||||||
|
### Binary Size Optimization
|
||||||
|
- **Release Profile**: Always maintain `opt-level = "z"`, `lto = true`, `codegen-units = 1`, `strip = true`, `panic = "abort"`.
|
||||||
|
- **Dependencies**:
|
||||||
|
- Run `cargo tree --duplicates` weekly to find and resolve duplicate versions.
|
||||||
|
- Run `cargo machete` to remove unused dependencies.
|
||||||
|
- Use `default-features = false` and explicitly opt-in to needed features.
|
||||||
|
|
||||||
|
### Memory Optimization
|
||||||
|
- **Strings**: Prefer `&str` over `String` where possible. Use `Cow<str>` for conditional ownership.
|
||||||
|
- **Collections**: Use `Vec::with_capacity` when size is known. Consider `SmallVec` for hot paths.
|
||||||
|
- **Allocations**: Minimize heap allocations in hot paths.
|
||||||
|
|
||||||
|
### Linting & Code Quality
|
||||||
|
- **Clippy**: Code MUST pass `cargo clippy --all-targets --all-features` with **0 warnings**.
|
||||||
|
- **No Allow**: Do not use `#[allow(clippy::...)]` unless absolutely necessary and documented. Fix the underlying issue.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔐 SECURITY DIRECTIVES - MANDATORY
|
||||||
|
|
||||||
|
### Error Handling - NO PANICS IN PRODUCTION
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// ❌ FORBIDDEN
|
||||||
|
value.unwrap()
|
||||||
|
value.expect("message")
|
||||||
|
panic!("error")
|
||||||
|
todo!()
|
||||||
|
unimplemented!()
|
||||||
|
|
||||||
|
// ✅ REQUIRED
|
||||||
|
value?
|
||||||
|
value.ok_or_else(|| Error::NotFound)?
|
||||||
|
value.unwrap_or_default()
|
||||||
|
value.unwrap_or_else(|e| { log::error!("{}", e); default })
|
||||||
|
if let Some(v) = value { ... }
|
||||||
|
match value { Ok(v) => v, Err(e) => return Err(e.into()) }
|
||||||
|
```
|
||||||
|
|
||||||
|
### Command Execution - USE SafeCommand
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// ❌ FORBIDDEN
|
||||||
|
Command::new("some_command").arg(user_input).output()
|
||||||
|
|
||||||
|
// ✅ REQUIRED
|
||||||
|
use crate::security::command_guard::SafeCommand;
|
||||||
|
SafeCommand::new("allowed_command")?
|
||||||
|
.arg("safe_arg")?
|
||||||
|
.execute()
|
||||||
|
```
|
||||||
|
|
||||||
|
### Error Responses - USE ErrorSanitizer
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// ❌ FORBIDDEN
|
||||||
|
Json(json!({ "error": e.to_string() }))
|
||||||
|
format!("Database error: {}", e)
|
||||||
|
|
||||||
|
// ✅ REQUIRED
|
||||||
|
use crate::security::error_sanitizer::log_and_sanitize;
|
||||||
|
let sanitized = log_and_sanitize(&e, "context", None);
|
||||||
|
(StatusCode::INTERNAL_SERVER_ERROR, sanitized)
|
||||||
|
```
|
||||||
|
|
||||||
|
### SQL - USE sql_guard
|
||||||
|
|
||||||
|
```rust
|
||||||
|
// ❌ FORBIDDEN
|
||||||
|
format!("SELECT * FROM {}", user_table)
|
||||||
|
|
||||||
|
// ✅ REQUIRED
|
||||||
|
use crate::security::sql_guard::{sanitize_identifier, validate_table_name};
|
||||||
|
let safe_table = sanitize_identifier(&user_table);
|
||||||
|
validate_table_name(&safe_table)?;
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ❌ ABSOLUTE PROHIBITIONS
|
||||||
|
|
||||||
|
```
|
||||||
|
❌ NEVER use .unwrap() or .expect() in production code (tests OK)
|
||||||
|
❌ NEVER use panic!(), todo!(), unimplemented!()
|
||||||
|
❌ NEVER use Command::new() directly - use SafeCommand
|
||||||
|
❌ NEVER return raw error strings to HTTP clients
|
||||||
|
❌ NEVER use #[allow()] in source code - FIX the code instead
|
||||||
|
❌ NEVER add lint exceptions to Cargo.toml - FIX the code instead
|
||||||
|
❌ NEVER use _ prefix for unused variables - DELETE or USE them
|
||||||
|
❌ NEVER leave unused imports or dead code
|
||||||
|
❌ NEVER add comments - code must be self-documenting
|
||||||
|
❌ NEVER modify Cargo.toml lints section!
|
||||||
|
❌ NEVER use CDN links - all assets must be local
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ✅ MANDATORY CODE PATTERNS
|
||||||
|
|
||||||
|
### Use Self in Impl Blocks
|
||||||
|
```rust
|
||||||
|
impl MyStruct {
|
||||||
|
fn new() -> Self { Self { } } // ✅ Not MyStruct
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Derive Eq with PartialEq
|
||||||
|
```rust
|
||||||
|
#[derive(PartialEq, Eq)] // ✅ Always both
|
||||||
|
struct MyStruct { }
|
||||||
|
```
|
||||||
|
|
||||||
|
### Inline Format Args
|
||||||
|
```rust
|
||||||
|
format!("Hello {name}") // ✅ Not format!("{}", name)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Combine Match Arms
|
||||||
|
```rust
|
||||||
|
match x {
|
||||||
|
A | B => do_thing(), // ✅ Combine identical arms
|
||||||
|
C => other(),
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🖥️ UI Architecture (botui + botserver)
|
||||||
|
|
||||||
|
### Two Servers During Development
|
||||||
|
|
||||||
|
| Server | Port | Purpose |
|
||||||
|
|--------|------|---------|
|
||||||
|
| **botui** | 3000 | Serves UI files + proxies API to botserver |
|
||||||
|
| **botserver** | 8088 | Backend API + embedded UI fallback |
|
||||||
|
|
||||||
|
### How It Works
|
||||||
|
|
||||||
|
```
|
||||||
|
Browser → localhost:3000 → botui (serves HTML/CSS/JS)
|
||||||
|
→ /api/* proxied to botserver:8088
|
||||||
|
→ /suite/* served from botui/ui/suite/
|
||||||
|
```
|
||||||
|
|
||||||
|
### Adding New Suite Apps
|
||||||
|
|
||||||
|
1. Create folder: `botui/ui/suite/<appname>/`
|
||||||
|
2. Add to `SUITE_DIRS` in `botui/src/ui_server/mod.rs`
|
||||||
|
3. Rebuild botui: `cargo build -p botui`
|
||||||
|
4. Add menu entry in `botui/ui/suite/index.html`
|
||||||
|
|
||||||
|
### Hot Reload
|
||||||
|
|
||||||
|
- **UI files (HTML/CSS/JS)**: Edit & refresh browser (no restart)
|
||||||
|
- **botui Rust code**: Rebuild + restart botui
|
||||||
|
- **botserver Rust code**: Rebuild + restart botserver
|
||||||
|
|
||||||
|
### Production (Single Binary)
|
||||||
|
|
||||||
|
When `botui/ui/suite/` folder not found, botserver uses **embedded UI** compiled into binary via `rust-embed`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🎨 FRONTEND STANDARDS
|
||||||
|
|
||||||
|
### HTMX-First Approach
|
||||||
|
- Use HTMX to minimize JavaScript
|
||||||
|
- Server returns HTML fragments, not JSON
|
||||||
|
- Use `hx-get`, `hx-post`, `hx-target`, `hx-swap`
|
||||||
|
- WebSocket via htmx-ws extension
|
||||||
|
|
||||||
|
### Local Assets Only - NO CDN
|
||||||
|
```html
|
||||||
|
<!-- ✅ CORRECT -->
|
||||||
|
<script src="js/vendor/htmx.min.js"></script>
|
||||||
|
|
||||||
|
<!-- ❌ WRONG -->
|
||||||
|
<script src="https://unpkg.com/htmx.org@1.9.10"></script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Vendor Libraries Location
|
||||||
|
```
|
||||||
|
ui/suite/js/vendor/
|
||||||
|
├── htmx.min.js
|
||||||
|
├── htmx-ws.js
|
||||||
|
├── marked.min.js
|
||||||
|
└── gsap.min.js
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 PROJECT-SPECIFIC PROMPTS
|
||||||
|
|
||||||
|
Each crate has its own PROMPT.md with specific guidelines:
|
||||||
|
|
||||||
|
| Crate | PROMPT.md Location | Focus |
|
||||||
|
|-------|-------------------|-------|
|
||||||
|
| botserver | `botserver/PROMPT.md` | API, security, Rhai BASIC |
|
||||||
|
| botui | `botui/PROMPT.md` | UI, HTMX, CSS design system |
|
||||||
|
| botapp | `botapp/PROMPT.md` | Tauri, desktop features |
|
||||||
|
| botlib | `botlib/PROMPT.md` | Shared types, errors |
|
||||||
|
| botbook | `botbook/PROMPT.md` | Documentation, mdBook |
|
||||||
|
| bottest | `bottest/PROMPT.md` | Test infrastructure |
|
||||||
|
|
||||||
|
### Special Prompts
|
||||||
|
| File | Purpose |
|
||||||
|
|------|---------|
|
||||||
|
| `botserver/src/tasks/PROMPT.md` | AutoTask LLM executor |
|
||||||
|
| `botserver/src/auto_task/APP_GENERATOR_PROMPT.md` | App generation |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 STARTING DEVELOPMENT
|
||||||
|
|
||||||
|
### Start Both Servers
|
||||||
|
```bash
|
||||||
|
# Terminal 1: botserver
|
||||||
|
cd botserver && cargo run -- --noconsole
|
||||||
|
|
||||||
|
# Terminal 2: botui
|
||||||
|
cd botui && BOTSERVER_URL="http://localhost:8088" cargo run
|
||||||
|
```
|
||||||
|
|
||||||
|
### Build Commands
|
||||||
|
```bash
|
||||||
|
# Check single crate
|
||||||
|
cargo check -p botserver
|
||||||
|
|
||||||
|
# Build workspace
|
||||||
|
cargo build
|
||||||
|
|
||||||
|
# Run tests
|
||||||
|
cargo test -p bottest
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 CONTINUATION PROMPT
|
||||||
|
|
||||||
|
When starting a new session or continuing work:
|
||||||
|
|
||||||
|
```
|
||||||
|
Continue on gb/ workspace. Follow PROMPT.md strictly:
|
||||||
|
|
||||||
|
1. Check current state with build/diagnostics
|
||||||
|
2. Fix ALL warnings and errors - NO #[allow()] attributes
|
||||||
|
3. Delete unused code, don't suppress warnings
|
||||||
|
4. Remove unused parameters, don't prefix with _
|
||||||
|
5. Verify after each fix batch
|
||||||
|
6. Loop until 0 warnings, 0 errors
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔑 REMEMBER
|
||||||
|
|
||||||
|
- **OFFLINE FIRST** - Fix all errors from list before compiling
|
||||||
|
- **ZERO WARNINGS, ZERO ERRORS** - The only acceptable state
|
||||||
|
- **FIX, DON'T SUPPRESS** - No #[allow()], no Cargo.toml lint exceptions
|
||||||
|
- **SECURITY FIRST** - No unwrap, no raw errors, no direct commands
|
||||||
|
- **READ BEFORE FIX** - Always understand context first
|
||||||
|
- **BATCH BY FILE** - Fix ALL errors in a file at once
|
||||||
|
- **WRITE ONCE** - Single edit per file with all fixes
|
||||||
|
- **VERIFY LAST** - Only compile/diagnostics after ALL fixes
|
||||||
|
- **DELETE DEAD CODE** - Don't keep unused code around
|
||||||
|
- **Version 6.2.0** - Do not change without approval
|
||||||
|
- **GIT WORKFLOW** - ALWAYS push to ALL repositories (github, pragmatismo)
|
||||||
2
botapp
2
botapp
|
|
@ -1 +1 @@
|
||||||
Subproject commit b5ee6e061acf1388aef777ddcd9a2bf84bd6ed57
|
Subproject commit 1a1e17fa1012e4db10a0f716c9b63a03b4863c9f
|
||||||
2
botbook
2
botbook
|
|
@ -1 +1 @@
|
||||||
Subproject commit 85696bb9070738f6bb865202f8c7de733f7c731a
|
Subproject commit 827e011ac05084396aaf2c3098409bf5e02b5cf9
|
||||||
2
botlib
2
botlib
|
|
@ -1 +1 @@
|
||||||
Subproject commit 2765fa2ebadc91435e8d90f068b4c96dbb77329b
|
Subproject commit bfaa68dc35e96ced2915d43ffe6fca8267a9a598
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 22a1954fac2f87a0a13b5e599771273172afc73a
|
Subproject commit 462a6dfa51b12f22e87712e613a559f66f9013cb
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 30345c66e2738ebe73d896841e54f655999e3630
|
Subproject commit 84458b2a6905af7db72b15f5e833bb7942ccdaa9
|
||||||
2
bottest
2
bottest
|
|
@ -1 +1 @@
|
||||||
Subproject commit 74e761de0dd5105885acf00183223a702a8436df
|
Subproject commit 706391b272e0fb7c5b2646cc4cc72180195e07f4
|
||||||
2
botui
2
botui
|
|
@ -1 +1 @@
|
||||||
Subproject commit 414d277ae1757834d2ddbd6225063b451e919788
|
Subproject commit 661edc09fa1063673e84b63d2dcb5cfbe0f91232
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
{
|
|
||||||
"base_url": "http://localhost:8300",
|
|
||||||
"default_org": {
|
|
||||||
"id": "358572039839154190",
|
|
||||||
"name": "default",
|
|
||||||
"domain": "default.localhost"
|
|
||||||
},
|
|
||||||
"default_user": {
|
|
||||||
"id": "admin",
|
|
||||||
"username": "admin",
|
|
||||||
"email": "admin@localhost",
|
|
||||||
"password": "",
|
|
||||||
"first_name": "Admin",
|
|
||||||
"last_name": "User"
|
|
||||||
},
|
|
||||||
"admin_token": "eW0mGnOlKjpYHsrZZNAh1o3_8qeyF1iKKgEj-Y63GBdjQbQmxKxEjsNmVLZ_DWRDK6I3_yI",
|
|
||||||
"project_id": "",
|
|
||||||
"client_id": "358572040510308366",
|
|
||||||
"client_secret": "WyZRbj5iMkOkbvvtJWivXVaaydhWX1TodavhnAhsivl8IDZ44v2QoqT5upfgmOfz"
|
|
||||||
}
|
|
||||||
12
package.json
12
package.json
|
|
@ -1,12 +0,0 @@
|
||||||
{
|
|
||||||
"name": "gb",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"main": "index.js",
|
|
||||||
"author": "Rodrigo Rodriguez (Pragmatismo) <me@rodrigorodriguez.com>",
|
|
||||||
"license": "MIT",
|
|
||||||
"devDependencies": {
|
|
||||||
"@playwright/test": "^1.58.1",
|
|
||||||
"@types/node": "^25.2.0"
|
|
||||||
},
|
|
||||||
"scripts": {}
|
|
||||||
}
|
|
||||||
|
|
@ -1,79 +0,0 @@
|
||||||
import { defineConfig, devices } from '@playwright/test';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read environment variables from file.
|
|
||||||
* https://github.com/motdotla/dotenv
|
|
||||||
*/
|
|
||||||
// import dotenv from 'dotenv';
|
|
||||||
// import path from 'path';
|
|
||||||
// dotenv.config({ path: path.resolve(__dirname, '.env') });
|
|
||||||
|
|
||||||
/**
|
|
||||||
* See https://playwright.dev/docs/test-configuration.
|
|
||||||
*/
|
|
||||||
export default defineConfig({
|
|
||||||
testDir: './tests',
|
|
||||||
/* Run tests in files in parallel */
|
|
||||||
fullyParallel: true,
|
|
||||||
/* Fail the build on CI if you accidentally left test.only in the source code. */
|
|
||||||
forbidOnly: !!process.env.CI,
|
|
||||||
/* Retry on CI only */
|
|
||||||
retries: process.env.CI ? 2 : 0,
|
|
||||||
/* Opt out of parallel tests on CI. */
|
|
||||||
workers: process.env.CI ? 1 : undefined,
|
|
||||||
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
|
|
||||||
reporter: 'html',
|
|
||||||
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
|
|
||||||
use: {
|
|
||||||
/* Base URL to use in actions like `await page.goto('')`. */
|
|
||||||
// baseURL: 'http://localhost:3000',
|
|
||||||
|
|
||||||
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
|
|
||||||
trace: 'on-first-retry',
|
|
||||||
},
|
|
||||||
|
|
||||||
/* Configure projects for major browsers */
|
|
||||||
projects: [
|
|
||||||
{
|
|
||||||
name: 'chromium',
|
|
||||||
use: { ...devices['Desktop Chrome'] },
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
name: 'firefox',
|
|
||||||
use: { ...devices['Desktop Firefox'] },
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
name: 'webkit',
|
|
||||||
use: { ...devices['Desktop Safari'] },
|
|
||||||
},
|
|
||||||
|
|
||||||
/* Test against mobile viewports. */
|
|
||||||
// {
|
|
||||||
// name: 'Mobile Chrome',
|
|
||||||
// use: { ...devices['Pixel 5'] },
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: 'Mobile Safari',
|
|
||||||
// use: { ...devices['iPhone 12'] },
|
|
||||||
// },
|
|
||||||
|
|
||||||
/* Test against branded browsers. */
|
|
||||||
// {
|
|
||||||
// name: 'Microsoft Edge',
|
|
||||||
// use: { ...devices['Desktop Edge'], channel: 'msedge' },
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// name: 'Google Chrome',
|
|
||||||
// use: { ...devices['Desktop Chrome'], channel: 'chrome' },
|
|
||||||
// },
|
|
||||||
],
|
|
||||||
|
|
||||||
/* Run your local dev server before starting the tests */
|
|
||||||
// webServer: {
|
|
||||||
// command: 'npm run start',
|
|
||||||
// url: 'http://localhost:3000',
|
|
||||||
// reuseExistingServer: !process.env.CI,
|
|
||||||
// },
|
|
||||||
});
|
|
||||||
1
reset.sh
1
reset.sh
|
|
@ -1 +0,0 @@
|
||||||
rm -rf botserver-stack/ ./work/ .env
|
|
||||||
28
restart.sh
28
restart.sh
|
|
@ -1,28 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
set -e
|
|
||||||
|
|
||||||
echo "🛑 Stopping existing processes..."
|
|
||||||
pkill -f botserver || true
|
|
||||||
pkill -f botui || true
|
|
||||||
pkill -f rustc || true
|
|
||||||
|
|
||||||
echo "🧹 Cleaning logs..."
|
|
||||||
rm -f botserver.log botui.log
|
|
||||||
|
|
||||||
echo "🔨 Building botserver..."
|
|
||||||
cargo build -p botserver
|
|
||||||
|
|
||||||
echo "🔨 Building botui..."
|
|
||||||
cargo build -p botui
|
|
||||||
|
|
||||||
echo "🚀 Starting botserver..."
|
|
||||||
RUST_LOG=info ./target/debug/botserver --noconsole > botserver.log 2>&1 &
|
|
||||||
BOTSERVER_PID=$!
|
|
||||||
|
|
||||||
echo "🚀 Starting botui..."
|
|
||||||
BOTSERVER_URL="https://localhost:8088" ./target/debug/botui > botui.log 2>&1 &
|
|
||||||
BOTUI_PID=$!
|
|
||||||
|
|
||||||
echo "✅ Started botserver (PID: $BOTSERVER_PID) and botui (PID: $BOTUI_PID)"
|
|
||||||
echo "📊 Monitor with: tail -f botserver.log botui.log"
|
|
||||||
echo "🌐 Access at: http://localhost:3000"
|
|
||||||
28
start.bas
28
start.bas
|
|
@ -1,28 +0,0 @@
|
||||||
REM Knowledge Base Website Crawler Bot - Start Template
|
|
||||||
REM Sets up bot context and crawled websites, then exits
|
|
||||||
|
|
||||||
REM Load bot introduction
|
|
||||||
intro = GET BOT MEMORY "introduction"
|
|
||||||
IF intro = "" THEN
|
|
||||||
intro = "I'm your documentation assistant with access to crawled websites."
|
|
||||||
END IF
|
|
||||||
|
|
||||||
REM Register websites for crawling (preprocessing mode)
|
|
||||||
USE WEBSITE "https://docs.python.org"
|
|
||||||
USE WEBSITE "https://developer.mozilla.org"
|
|
||||||
USE WEBSITE "https://stackoverflow.com"
|
|
||||||
|
|
||||||
REM Set context for LLM
|
|
||||||
SET CONTEXT "role" AS intro
|
|
||||||
SET CONTEXT "capabilities" AS "I can search Python docs, MDN web docs, and Stack Overflow."
|
|
||||||
|
|
||||||
REM Configure suggestion buttons
|
|
||||||
CLEAR SUGGESTIONS
|
|
||||||
ADD SUGGESTION "python" AS "How do I use Python dictionaries?"
|
|
||||||
ADD SUGGESTION "javascript" AS "Explain JavaScript async/await"
|
|
||||||
ADD SUGGESTION "web" AS "What is the DOM in web development?"
|
|
||||||
|
|
||||||
REM Initial greeting
|
|
||||||
TALK intro
|
|
||||||
TALK "I have access to Python documentation, MDN web docs, and Stack Overflow."
|
|
||||||
TALK "Ask me any programming question!"
|
|
||||||
4
stop.sh
4
stop.sh
|
|
@ -1,4 +0,0 @@
|
||||||
pkill botui
|
|
||||||
pkill botserver -9
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
import { test, expect } from '@playwright/test';
|
|
||||||
|
|
||||||
test('has title', async ({ page }) => {
|
|
||||||
await page.goto('https://playwright.dev/');
|
|
||||||
|
|
||||||
// Expect a title "to contain" a substring.
|
|
||||||
await expect(page).toHaveTitle(/Playwright/);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('get started link', async ({ page }) => {
|
|
||||||
await page.goto('https://playwright.dev/');
|
|
||||||
|
|
||||||
// Click the get started link.
|
|
||||||
await page.getByRole('link', { name: 'Get started' }).click();
|
|
||||||
|
|
||||||
// Expects page to have a heading with the name of Installation.
|
|
||||||
await expect(page.getByRole('heading', { name: 'Installation' })).toBeVisible();
|
|
||||||
});
|
|
||||||
41
yarn.lock
41
yarn.lock
|
|
@ -1,41 +0,0 @@
|
||||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
|
||||||
# yarn lockfile v1
|
|
||||||
|
|
||||||
|
|
||||||
"@playwright/test@^1.58.1":
|
|
||||||
version "1.58.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/@playwright/test/-/test-1.58.1.tgz#891dcd1da815cb1042490531f6d8778988509d22"
|
|
||||||
integrity sha512-6LdVIUERWxQMmUSSQi0I53GgCBYgM2RpGngCPY7hSeju+VrKjq3lvs7HpJoPbDiY5QM5EYRtRX5fvrinnMAz3w==
|
|
||||||
dependencies:
|
|
||||||
playwright "1.58.1"
|
|
||||||
|
|
||||||
"@types/node@^25.2.0":
|
|
||||||
version "25.2.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-25.2.0.tgz#015b7d228470c1dcbfc17fe9c63039d216b4d782"
|
|
||||||
integrity sha512-DZ8VwRFUNzuqJ5khrvwMXHmvPe+zGayJhr2CDNiKB1WBE1ST8Djl00D0IC4vvNmHMdj6DlbYRIaFE7WHjlDl5w==
|
|
||||||
dependencies:
|
|
||||||
undici-types "~7.16.0"
|
|
||||||
|
|
||||||
fsevents@2.3.2:
|
|
||||||
version "2.3.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
|
|
||||||
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
|
|
||||||
|
|
||||||
playwright-core@1.58.1:
|
|
||||||
version "1.58.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.58.1.tgz#d63be2c9b7dcbdb035beddd4b42437bd3ca89107"
|
|
||||||
integrity sha512-bcWzOaTxcW+VOOGBCQgnaKToLJ65d6AqfLVKEWvexyS3AS6rbXl+xdpYRMGSRBClPvyj44njOWoxjNdL/H9UNg==
|
|
||||||
|
|
||||||
playwright@1.58.1:
|
|
||||||
version "1.58.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.58.1.tgz#63300e77a604c77264e1b499c0d94b54ed96d6ba"
|
|
||||||
integrity sha512-+2uTZHxSCcxjvGc5C891LrS1/NlxglGxzrC4seZiVjcYVQfUa87wBL6rTDqzGjuoWNjnBzRqKmF6zRYGMvQUaQ==
|
|
||||||
dependencies:
|
|
||||||
playwright-core "1.58.1"
|
|
||||||
optionalDependencies:
|
|
||||||
fsevents "2.3.2"
|
|
||||||
|
|
||||||
undici-types@~7.16.0:
|
|
||||||
version "7.16.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.16.0.tgz#ffccdff36aea4884cbfce9a750a0580224f58a46"
|
|
||||||
integrity sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==
|
|
||||||
Loading…
Add table
Reference in a new issue