Compare commits
306 Commits
mcp-client
...
v2023.0.19
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5c456fd4d5 | ||
|
|
38c247e350 | ||
|
|
0c8f72124a | ||
|
|
80ed6b1525 | ||
|
|
4424b3f208 | ||
|
|
2c75abce09 | ||
|
|
4e15eb197f | ||
|
|
a7544b4f8c | ||
|
|
d126aad172 | ||
|
|
acc5c0de50 | ||
|
|
3391da111d | ||
|
|
e37ce96956 | ||
|
|
c51831c975 | ||
|
|
180aa39de4 | ||
|
|
3bd780782e | ||
|
|
f9ba2f79c2 | ||
|
|
d9493de2be | ||
|
|
bc9a623742 | ||
|
|
532edbf274 | ||
|
|
1585692328 | ||
|
|
083f565b12 | ||
|
|
f7f7438c9e | ||
|
|
19934a93bb | ||
|
|
577cfe5bdc | ||
|
|
43ac6afae1 | ||
|
|
8cc11703d3 | ||
|
|
4f7a116378 | ||
|
|
513793d9ce | ||
|
|
67f32b6734 | ||
|
|
66813d67fe | ||
|
|
a38691ed53 | ||
|
|
deeefdcfbf | ||
|
|
db292511b1 | ||
|
|
1a5334c1ce | ||
|
|
11002abe39 | ||
|
|
d922dcb062 | ||
|
|
6fcaa18e86 | ||
|
|
7664c941dd | ||
|
|
6f5cb528c6 | ||
|
|
ebb78922f0 | ||
|
|
2285fe9f1c | ||
|
|
38ba8625d8 | ||
|
|
ab5681c7ad | ||
|
|
f66dcb9267 | ||
|
|
1b6cfbac77 | ||
|
|
4c27e788ea | ||
|
|
769da0b052 | ||
|
|
6b60c86300 | ||
|
|
30c1b5e8c7 | ||
|
|
10af9b6f99 | ||
|
|
aa8c066f2d | ||
|
|
b913b74449 | ||
|
|
b71adce50b | ||
|
|
0fbb44c701 | ||
|
|
de335e8637 | ||
|
|
2999f63a4c | ||
|
|
2abc5e6f0b | ||
|
|
639de4321e | ||
|
|
b3c461afdd | ||
|
|
7d154800a0 | ||
|
|
b48ed0399e | ||
|
|
c5d6e7d74a | ||
|
|
e82f915363 | ||
|
|
3128e9ce76 | ||
|
|
bc0e86757c | ||
|
|
fec99916c2 | ||
|
|
3b5d059b11 | ||
|
|
c3fe2acc8a | ||
|
|
4d002c412b | ||
|
|
46d152b5f1 | ||
|
|
25fa81ebbc | ||
|
|
7c2de3c360 | ||
|
|
3a3b187cd0 | ||
|
|
3226bbe083 | ||
|
|
a1e4e0e6c9 | ||
|
|
b3aa8b893b | ||
|
|
f057139634 | ||
|
|
71a2b11ab4 | ||
|
|
587254a0e7 | ||
|
|
9f4de66f3c | ||
|
|
b0d8908724 | ||
|
|
15c22d98c6 | ||
|
|
3105ae0edc | ||
|
|
11a89f06c1 | ||
|
|
9cbe24e740 | ||
|
|
bfbed13b8f | ||
|
|
2268de6321 | ||
|
|
dd99aa7fcd | ||
|
|
be436bb706 | ||
|
|
bd48726f44 | ||
|
|
10bea83f98 | ||
|
|
8122b4fb84 | ||
|
|
3ae57fb2d8 | ||
|
|
6dc3eecca4 | ||
|
|
9d1d732154 | ||
|
|
8a117415b7 | ||
|
|
d36623ebc9 | ||
|
|
94a3ae3696 | ||
|
|
2836a28988 | ||
|
|
946d7dc89e | ||
|
|
af6300f18b | ||
|
|
905cb4b18e | ||
|
|
305ed09547 | ||
|
|
643356bad3 | ||
|
|
e458675627 | ||
|
|
91e3853692 | ||
|
|
5f0876a136 | ||
|
|
3a38127fb4 | ||
|
|
f3b6070235 | ||
|
|
5e6e78eb9e | ||
|
|
9b66a1d1a8 | ||
|
|
e954d0d7bc | ||
|
|
dab2df7e79 | ||
|
|
bc40e22008 | ||
|
|
eef262c398 | ||
|
|
8eab6e14db | ||
|
|
ded33a110a | ||
|
|
e448a7602a | ||
|
|
4c22215ca5 | ||
|
|
4f501abb72 | ||
|
|
b2dcc38982 | ||
|
|
11b719955b | ||
|
|
d563ac63db | ||
|
|
6d826064c6 | ||
|
|
d30b9d6518 | ||
|
|
8da3364d0f | ||
|
|
07c372b7f5 | ||
|
|
7e01f38253 | ||
|
|
ba637009a7 | ||
|
|
da7388e510 | ||
|
|
3ec88fc896 | ||
|
|
1c9381b2bd | ||
|
|
06349b8d5b | ||
|
|
6dc7dc6ad2 | ||
|
|
f981a15ec3 | ||
|
|
8b648c0301 | ||
|
|
83ce09075b | ||
|
|
168dfb9f6b | ||
|
|
9b8961c23d | ||
|
|
89bca42ee6 | ||
|
|
07d2a43a17 | ||
|
|
c84f2afd09 | ||
|
|
df4dbaecc8 | ||
|
|
d9bf03cefe | ||
|
|
39223e8d89 | ||
|
|
67925e18b2 | ||
|
|
89ad65513d | ||
|
|
90166ddfa3 | ||
|
|
0981b23faf | ||
|
|
664f3b4d87 | ||
|
|
dc97b91a4e | ||
|
|
d310272d19 | ||
|
|
f1be3f01e1 | ||
|
|
c57b6e1d73 | ||
|
|
a938dc45f0 | ||
|
|
bb139744a1 | ||
|
|
3aa3e09552 | ||
|
|
74abfd21b8 | ||
|
|
e703817ba2 | ||
|
|
80dd1e457b | ||
|
|
ea9f8d3ab2 | ||
|
|
fa222bdf12 | ||
|
|
45b360dabd | ||
|
|
5923399359 | ||
|
|
f4600f3e90 | ||
|
|
f883837685 | ||
|
|
b58bc409f0 | ||
|
|
e893e539bb | ||
|
|
90294fbb5d | ||
|
|
ae65f222bc | ||
|
|
1b9813fb4c | ||
|
|
b708b5ae41 | ||
|
|
df136fa915 | ||
|
|
f8329f5b8d | ||
|
|
21141090de | ||
|
|
c0d9740a7d | ||
|
|
afcf630443 | ||
|
|
1fe2c9826a | ||
|
|
7272b80a3f | ||
|
|
92114b7368 | ||
|
|
f39d3e7eed | ||
|
|
cbe0d27a5e | ||
|
|
cd39699467 | ||
|
|
b3ea67aacf | ||
|
|
db4ed9797c | ||
|
|
1ea7d7d685 | ||
|
|
2df725b57a | ||
|
|
74e6648249 | ||
|
|
1026350d9c | ||
|
|
98fb87874d | ||
|
|
41fc3afdc1 | ||
|
|
83dbf46ba4 | ||
|
|
0b2e35bdde | ||
|
|
d90a7331c9 | ||
|
|
264e64a996 | ||
|
|
8915915c47 | ||
|
|
951ed787fa | ||
|
|
64ef6b0c22 | ||
|
|
ef18377b3c | ||
|
|
5904b6fded | ||
|
|
f4401e77bb | ||
|
|
efa5455a7b | ||
|
|
619c8d9e72 | ||
|
|
bdf89ac288 | ||
|
|
debd3c8185 | ||
|
|
f81a3ae8e7 | ||
|
|
7d4e9894c3 | ||
|
|
4bf22d8a60 | ||
|
|
8be4971a23 | ||
|
|
359e916b73 | ||
|
|
68058f3e41 | ||
|
|
0c6fa3e634 | ||
|
|
0fa25c6335 | ||
|
|
5684479f1d | ||
|
|
2d1603601c | ||
|
|
f5394b2210 | ||
|
|
833db5df06 | ||
|
|
525ac7e980 | ||
|
|
44a747c80a | ||
|
|
2056e7f40a | ||
|
|
9b6c1ad364 | ||
|
|
34987bcacb | ||
|
|
b62c11222a | ||
|
|
b3cee3ace3 | ||
|
|
222c054c95 | ||
|
|
46f18a2491 | ||
|
|
f2ca8e2753 | ||
|
|
b0d243c378 | ||
|
|
6161fb86c8 | ||
|
|
b09cc91fe5 | ||
|
|
ef1638cbb3 | ||
|
|
00ef8743f2 | ||
|
|
68222659e3 | ||
|
|
69420a4bba | ||
|
|
0161bbaeb1 | ||
|
|
948dbfe3cc | ||
|
|
338ba8b189 | ||
|
|
ca4655b441 | ||
|
|
bf37499428 | ||
|
|
0b94b57e2a | ||
|
|
fc40aead98 | ||
|
|
7d7f934e6a | ||
|
|
d5fbf4d622 | ||
|
|
e4f6c919dc | ||
|
|
4d806ff2b1 | ||
|
|
bf8f12274f | ||
|
|
f4f438d9fe | ||
|
|
2434f373be | ||
|
|
2bb2061f97 | ||
|
|
2c011a5c2a | ||
|
|
f66b0ccea1 | ||
|
|
665dd8447d | ||
|
|
1b61ce31e6 | ||
|
|
ef4d960698 | ||
|
|
b6d557b632 | ||
|
|
b700bd356c | ||
|
|
620dd7d3ef | ||
|
|
6575121902 | ||
|
|
7c1755a0dc | ||
|
|
8ad301a666 | ||
|
|
ae24cd4939 | ||
|
|
7152e1845e | ||
|
|
96c1dd4081 | ||
|
|
87c7b3a663 | ||
|
|
c1be46a539 | ||
|
|
4655e0018b | ||
|
|
da5ba2e3be | ||
|
|
aaf95f565f | ||
|
|
f32b984e77 | ||
|
|
548aa4c7cd | ||
|
|
0ccceaac77 | ||
|
|
70f534f1d8 | ||
|
|
61fe95b300 | ||
|
|
915e0e8613 | ||
|
|
aace2580da | ||
|
|
3d36905664 | ||
|
|
0d671423da | ||
|
|
aebfcb9437 | ||
|
|
be7ef7beb1 | ||
|
|
d77ed0c5cc | ||
|
|
e57e7bcec5 | ||
|
|
a637842ce4 | ||
|
|
fc54ec49af | ||
|
|
5c43d8510a | ||
|
|
83f84ded8d | ||
|
|
5658da34a2 | ||
|
|
38e8ef6535 | ||
|
|
8c89b06238 | ||
|
|
d85c021305 | ||
|
|
83bb18df03 | ||
|
|
93105a3e89 | ||
|
|
ba3b899115 | ||
|
|
fcfbc1d1da | ||
|
|
72486b448c | ||
|
|
7dea1b7870 | ||
|
|
4de2c496c9 | ||
|
|
9e1393a392 | ||
|
|
0901690ed6 | ||
|
|
95303648cc | ||
|
|
1dbb08c045 | ||
|
|
00a7d9a180 | ||
|
|
6c549dc086 | ||
|
|
dc368e326a | ||
|
|
e42188a627 | ||
|
|
7a6a337eff | ||
|
|
3907344884 |
@@ -1,72 +0,0 @@
|
|||||||
# Claude Context: Detaching Tauri from Yaak
|
|
||||||
|
|
||||||
## Goal
|
|
||||||
Make Yaak runnable as a standalone CLI without Tauri as a dependency. The core Rust crates in `crates/` should be usable independently, while Tauri-specific code lives in `crates-tauri/`.
|
|
||||||
|
|
||||||
## Project Structure
|
|
||||||
```
|
|
||||||
crates/ # Core crates - should NOT depend on Tauri
|
|
||||||
crates-tauri/ # Tauri-specific crates (yaak-app, yaak-tauri-utils, etc.)
|
|
||||||
crates-cli/ # CLI crate (yaak-cli)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Completed Work
|
|
||||||
|
|
||||||
### 1. Folder Restructure
|
|
||||||
- Moved Tauri-dependent app code to `crates-tauri/yaak-app/`
|
|
||||||
- Created `crates-tauri/yaak-tauri-utils/` for shared Tauri utilities (window traits, api_client, error handling)
|
|
||||||
- Created `crates-cli/yaak-cli/` for the standalone CLI
|
|
||||||
|
|
||||||
### 2. Decoupled Crates (no longer depend on Tauri)
|
|
||||||
- **yaak-models**: Uses `init_standalone()` pattern for CLI database access
|
|
||||||
- **yaak-http**: Removed Tauri plugin, HttpConnectionManager initialized in yaak-app setup
|
|
||||||
- **yaak-common**: Only contains Tauri-free utilities (serde, platform)
|
|
||||||
- **yaak-crypto**: Removed Tauri plugin, EncryptionManager initialized in yaak-app setup, commands moved to yaak-app
|
|
||||||
- **yaak-grpc**: Replaced AppHandle with GrpcConfig struct, uses tokio::process::Command instead of Tauri sidecar
|
|
||||||
|
|
||||||
### 3. CLI Implementation
|
|
||||||
- Basic CLI at `crates-cli/yaak-cli/src/main.rs`
|
|
||||||
- Commands: workspaces, requests, send (by ID), get (ad-hoc URL), create
|
|
||||||
- Uses same database as Tauri app via `yaak_models::init_standalone()`
|
|
||||||
|
|
||||||
## Remaining Work
|
|
||||||
|
|
||||||
### Crates Still Depending on Tauri (in `crates/`)
|
|
||||||
1. **yaak-git** (3 files) - Moderate complexity
|
|
||||||
2. **yaak-plugins** (13 files) - **Hardest** - deeply integrated with Tauri for plugin-to-window communication
|
|
||||||
3. **yaak-sync** (4 files) - Moderate complexity
|
|
||||||
4. **yaak-ws** (5 files) - Moderate complexity
|
|
||||||
|
|
||||||
### Pattern for Decoupling
|
|
||||||
1. Remove Tauri plugin `init()` function from the crate
|
|
||||||
2. Move commands to `yaak-app/src/commands.rs` or keep inline in `lib.rs`
|
|
||||||
3. Move extension traits (e.g., `SomethingManagerExt`) to yaak-app or yaak-tauri-utils
|
|
||||||
4. Initialize managers in yaak-app's `.setup()` block
|
|
||||||
5. Remove `tauri` from Cargo.toml dependencies
|
|
||||||
6. Update `crates-tauri/yaak-app/capabilities/default.json` to remove the plugin permission
|
|
||||||
7. Replace `tauri::async_runtime::block_on` with `tokio::runtime::Handle::current().block_on()`
|
|
||||||
|
|
||||||
## Key Files
|
|
||||||
- `crates-tauri/yaak-app/src/lib.rs` - Main Tauri app, setup block initializes managers
|
|
||||||
- `crates-tauri/yaak-app/src/commands.rs` - Migrated Tauri commands
|
|
||||||
- `crates-tauri/yaak-app/src/models_ext.rs` - Database plugin and extension traits
|
|
||||||
- `crates-tauri/yaak-tauri-utils/src/window.rs` - WorkspaceWindowTrait for window state
|
|
||||||
- `crates/yaak-models/src/lib.rs` - Contains `init_standalone()` for CLI usage
|
|
||||||
|
|
||||||
## Git Branch
|
|
||||||
Working on `detach-tauri` branch.
|
|
||||||
|
|
||||||
## Recent Commits
|
|
||||||
```
|
|
||||||
c40cff40 Remove Tauri dependencies from yaak-crypto and yaak-grpc
|
|
||||||
df495f1d Move Tauri utilities from yaak-common to yaak-tauri-utils
|
|
||||||
481e0273 Remove Tauri dependencies from yaak-http and yaak-common
|
|
||||||
10568ac3 Add HTTP request sending to yaak-cli
|
|
||||||
bcb7d600 Add yaak-cli stub with basic database access
|
|
||||||
e718a5f1 Refactor models_ext to use init_standalone from yaak-models
|
|
||||||
```
|
|
||||||
|
|
||||||
## Testing
|
|
||||||
- Run `cargo check -p <crate>` to verify a crate builds without Tauri
|
|
||||||
- Run `npm run app-dev` to test the Tauri app still works
|
|
||||||
- Run `cargo run -p yaak-cli -- --help` to test the CLI
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
---
|
|
||||||
description: Review a PR in a new worktree
|
|
||||||
allowed-tools: Bash(git worktree:*), Bash(gh pr:*)
|
|
||||||
---
|
|
||||||
|
|
||||||
Review a GitHub pull request in a new git worktree.
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
```
|
|
||||||
/review-pr <PR_NUMBER>
|
|
||||||
```
|
|
||||||
|
|
||||||
## What to do
|
|
||||||
|
|
||||||
1. List all open pull requests and ask the user to select one
|
|
||||||
2. Get PR information using `gh pr view <PR_NUMBER> --json number,headRefName`
|
|
||||||
3. Extract the branch name from the PR
|
|
||||||
4. Create a new worktree at `../yaak-worktrees/pr-<PR_NUMBER>` using `git worktree add` with a timeout of at least 300000ms (5 minutes) since the post-checkout hook runs a bootstrap script
|
|
||||||
5. Checkout the PR branch in the new worktree using `gh pr checkout <PR_NUMBER>`
|
|
||||||
6. The post-checkout hook will automatically:
|
|
||||||
- Create `.env.local` with unique ports
|
|
||||||
- Copy editor config folders
|
|
||||||
- Run `npm install && npm run bootstrap`
|
|
||||||
7. Inform the user:
|
|
||||||
- Where the worktree was created
|
|
||||||
- What ports were assigned
|
|
||||||
- How to access it (cd command)
|
|
||||||
- How to run the dev server
|
|
||||||
- How to remove the worktree when done
|
|
||||||
|
|
||||||
## Example Output
|
|
||||||
|
|
||||||
```
|
|
||||||
Created worktree for PR #123 at ../yaak-worktrees/pr-123
|
|
||||||
Branch: feature-auth
|
|
||||||
Ports: Vite (1421), MCP (64344)
|
|
||||||
|
|
||||||
To start working:
|
|
||||||
cd ../yaak-worktrees/pr-123
|
|
||||||
npm run app-dev
|
|
||||||
|
|
||||||
To remove when done:
|
|
||||||
git worktree remove ../yaak-worktrees/pr-123
|
|
||||||
```
|
|
||||||
|
|
||||||
## Error Handling
|
|
||||||
|
|
||||||
- If the PR doesn't exist, show a helpful error
|
|
||||||
- If the worktree already exists, inform the user and ask if they want to remove and recreate it
|
|
||||||
- If `gh` CLI is not available, inform the user to install it
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
---
|
|
||||||
description: Generate formatted release notes for Yaak releases
|
|
||||||
allowed-tools: Bash(git tag:*)
|
|
||||||
---
|
|
||||||
|
|
||||||
Generate formatted release notes for Yaak releases by analyzing git history and pull request descriptions.
|
|
||||||
|
|
||||||
## What to do
|
|
||||||
|
|
||||||
1. Identifies the version tag and previous version
|
|
||||||
2. Retrieves all commits between versions
|
|
||||||
- If the version is a beta version, it retrieves commits between the beta version and previous beta version
|
|
||||||
- If the version is a stable version, it retrieves commits between the stable version and the previous stable version
|
|
||||||
3. Fetches PR descriptions for linked issues to find:
|
|
||||||
- Feedback URLs (feedback.yaak.app)
|
|
||||||
- Additional context and descriptions
|
|
||||||
- Installation links for plugins
|
|
||||||
4. Formats the release notes using the standard Yaak format:
|
|
||||||
- Changelog badge at the top
|
|
||||||
- Bulleted list of changes with PR links
|
|
||||||
- Feedback links where available
|
|
||||||
- Full changelog comparison link at the bottom
|
|
||||||
|
|
||||||
## Output Format
|
|
||||||
|
|
||||||
The skill generates markdown-formatted release notes following this structure:
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
[](https://yaak.app/changelog/VERSION)
|
|
||||||
|
|
||||||
- Feature/fix description in by @username [#123](https://github.com/mountain-loop/yaak/pull/123)
|
|
||||||
- [Linked feedback item](https://feedback.yaak.app/p/item) by @username in [#456](https://github.com/mountain-loop/yaak/pull/456)
|
|
||||||
- A simple item that doesn't have a feedback or PR link
|
|
||||||
|
|
||||||
**Full Changelog**: https://github.com/mountain-loop/yaak/compare/vPREV...vCURRENT
|
|
||||||
```
|
|
||||||
|
|
||||||
**IMPORTANT**: Always add a blank lines around the markdown code fence and output the markdown code block last
|
|
||||||
**IMPORTANT**: PRs by `@gschier` should not mention the @username
|
|
||||||
|
|
||||||
## After Generating Release Notes
|
|
||||||
|
|
||||||
After outputting the release notes, ask the user if they would like to create a draft GitHub release with these notes. If they confirm, create the release using:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
gh release create <tag> --draft --prerelease --title "<tag>" --notes '<release notes>'
|
|
||||||
```
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
# Project Rules
|
|
||||||
|
|
||||||
## General Development
|
|
||||||
|
|
||||||
- **NEVER** commit or push without explicit confirmation
|
|
||||||
|
|
||||||
## Build and Lint
|
|
||||||
|
|
||||||
- **ALWAYS** run `npm run lint` after modifying TypeScript or JavaScript files
|
|
||||||
- Run `npm run bootstrap` after changing plugin runtime or MCP server code
|
|
||||||
|
|
||||||
## Plugin System
|
|
||||||
|
|
||||||
### Backend Constraints
|
|
||||||
|
|
||||||
- Always use `UpdateSource::Plugin` when calling database methods from plugin events
|
|
||||||
- Never send timestamps (`createdAt`, `updatedAt`) from TypeScript - Rust backend controls these
|
|
||||||
- Backend uses `NaiveDateTime` (no timezone) so avoid sending ISO timestamp strings
|
|
||||||
|
|
||||||
### MCP Server
|
|
||||||
|
|
||||||
- MCP server has **no active window context** - cannot call `window.workspaceId()`
|
|
||||||
- Get workspace ID from `workspaceCtx.yaak.workspace.list()` instead
|
|
||||||
|
|
||||||
## Rust Type Generation
|
|
||||||
|
|
||||||
- Run `cargo test --package yaak-plugins` (and for other crates) to regenerate TypeScript bindings after modifying Rust event types
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
# Worktree Management Skill
|
|
||||||
|
|
||||||
## Creating Worktrees
|
|
||||||
|
|
||||||
When creating git worktrees for this project, ALWAYS use the path format:
|
|
||||||
```
|
|
||||||
../yaak-worktrees/<NAME>
|
|
||||||
```
|
|
||||||
|
|
||||||
For example:
|
|
||||||
- `git worktree add ../yaak-worktrees/feature-auth`
|
|
||||||
- `git worktree add ../yaak-worktrees/bugfix-login`
|
|
||||||
- `git worktree add ../yaak-worktrees/refactor-api`
|
|
||||||
|
|
||||||
## What Happens Automatically
|
|
||||||
|
|
||||||
The post-checkout hook will automatically:
|
|
||||||
1. Create `.env.local` with unique ports (YAAK_DEV_PORT and YAAK_PLUGIN_MCP_SERVER_PORT)
|
|
||||||
2. Copy gitignored editor config folders (.zed, .idea, etc.)
|
|
||||||
3. Run `npm install && npm run bootstrap`
|
|
||||||
|
|
||||||
## Deleting Worktrees
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git worktree remove ../yaak-worktrees/<NAME>
|
|
||||||
```
|
|
||||||
|
|
||||||
## Port Assignments
|
|
||||||
|
|
||||||
- Main worktree: 1420 (Vite), 64343 (MCP)
|
|
||||||
- First worktree: 1421, 64344
|
|
||||||
- Second worktree: 1422, 64345
|
|
||||||
- etc.
|
|
||||||
|
|
||||||
Each worktree can run `npm run app-dev` simultaneously without conflicts.
|
|
||||||
5
.eslintignore
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
node_modules/
|
||||||
|
dist/
|
||||||
|
.prettierrc.cjs
|
||||||
|
.eslintrc.cjs
|
||||||
|
env.d.ts
|
||||||
37
.eslintrc.cjs
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
module.exports = {
|
||||||
|
extends: [
|
||||||
|
"eslint:recommended",
|
||||||
|
"plugin:react/recommended",
|
||||||
|
"plugin:react-hooks/recommended",
|
||||||
|
"plugin:import/recommended",
|
||||||
|
"plugin:jsx-a11y/recommended",
|
||||||
|
"plugin:@typescript-eslint/recommended",
|
||||||
|
"eslint-config-prettier"
|
||||||
|
],
|
||||||
|
parser: "@typescript-eslint/parser",
|
||||||
|
parserOptions: {
|
||||||
|
project: ["./tsconfig.json"]
|
||||||
|
},
|
||||||
|
ignorePatterns: ["src-tauri/**/*"],
|
||||||
|
settings: {
|
||||||
|
react: {
|
||||||
|
version: "detect"
|
||||||
|
},
|
||||||
|
"import/resolver": {
|
||||||
|
node: {
|
||||||
|
paths: ["src-web"],
|
||||||
|
extensions: [".ts", ".tsx"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
"jsx-a11y/no-autofocus": "off",
|
||||||
|
"react/react-in-jsx-scope": "off",
|
||||||
|
"import/no-unresolved": "off",
|
||||||
|
"@typescript-eslint/consistent-type-imports": ["error", {
|
||||||
|
prefer: "type-imports",
|
||||||
|
disallowTypeAnnotations: true,
|
||||||
|
fixStyle: "separate-type-imports"
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
};
|
||||||
7
.gitattributes
vendored
@@ -1,7 +0,0 @@
|
|||||||
crates-tauri/yaak-app/vendored/**/* linguist-generated=true
|
|
||||||
crates-tauri/yaak-app/gen/schemas/**/* linguist-generated=true
|
|
||||||
**/bindings/* linguist-generated=true
|
|
||||||
crates/yaak-templates/pkg/* linguist-generated=true
|
|
||||||
|
|
||||||
# Ensure consistent line endings for test files that check exact content
|
|
||||||
crates/yaak-http/tests/test.txt text eol=lf
|
|
||||||
3
.github/FUNDING.yml
vendored
@@ -1,3 +0,0 @@
|
|||||||
# These are supported funding model platforms
|
|
||||||
|
|
||||||
github: gschier
|
|
||||||
38
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -1,38 +0,0 @@
|
|||||||
---
|
|
||||||
name: Bug report
|
|
||||||
about: Create a report to help us improve
|
|
||||||
title: ''
|
|
||||||
labels: ''
|
|
||||||
assignees: ''
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**Describe the bug**
|
|
||||||
A clear and concise description of what the bug is.
|
|
||||||
|
|
||||||
**To Reproduce**
|
|
||||||
Steps to reproduce the behavior:
|
|
||||||
1. Go to '...'
|
|
||||||
2. Click on '....'
|
|
||||||
3. Scroll down to '....'
|
|
||||||
4. See error
|
|
||||||
|
|
||||||
**Expected behavior**
|
|
||||||
A clear and concise description of what you expected to happen.
|
|
||||||
|
|
||||||
**Screenshots**
|
|
||||||
If applicable, add screenshots to help explain your problem.
|
|
||||||
|
|
||||||
**Desktop (please complete the following information):**
|
|
||||||
- OS: [e.g. iOS]
|
|
||||||
- Browser [e.g. chrome, safari]
|
|
||||||
- Version [e.g. 22]
|
|
||||||
|
|
||||||
**Smartphone (please complete the following information):**
|
|
||||||
- Device: [e.g. iPhone6]
|
|
||||||
- OS: [e.g. iOS8.1]
|
|
||||||
- Browser [e.g. stock browser, safari]
|
|
||||||
- Version [e.g. 22]
|
|
||||||
|
|
||||||
**Additional context**
|
|
||||||
Add any other context about the problem here.
|
|
||||||
5
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,5 +0,0 @@
|
|||||||
blank_issues_enabled: false
|
|
||||||
contact_links:
|
|
||||||
- name: Bugs, Feedback, Feature Requests, and Questions
|
|
||||||
url: https://feedback.yaak.app
|
|
||||||
about: "Please report to Yaak's public feedback board. Issues will be created and linked here when applicable."
|
|
||||||
69
.github/workflows/artifacts.yml
vendored
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
name: Generate Artifacts
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags: [ v* ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-artifacts:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- os: macos-12
|
||||||
|
target: aarch64-apple-darwin
|
||||||
|
- os: macos-latest
|
||||||
|
target: x86_64-apple-darwin
|
||||||
|
- os: windows-2022
|
||||||
|
target: x86_64-pc-windows-msvc
|
||||||
|
- os: ubuntu-20.04
|
||||||
|
target: x86_64-unknown-linux-gnu
|
||||||
|
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- uses: dtolnay/rust-toolchain@stable
|
||||||
|
with:
|
||||||
|
targets: ${{ matrix.target }}
|
||||||
|
- name: Cache Rust
|
||||||
|
uses: actions/cache@v2
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
~/.cargo/registry
|
||||||
|
~/.cargo/git
|
||||||
|
./src-tauri/target
|
||||||
|
key: ${{ runner.os }}-cargo-${{ hashFiles('src-tauri/Cargo.lock') }}
|
||||||
|
- uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 18
|
||||||
|
cache: 'npm'
|
||||||
|
- name: install dependencies (ubuntu only)
|
||||||
|
if: matrix.os == 'ubuntu-20.04'
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libappindicator3-dev librsvg2-dev patchelf
|
||||||
|
- name: Install dependencies
|
||||||
|
run: npm ci
|
||||||
|
- name: Run tests
|
||||||
|
run: npm test
|
||||||
|
# Pin dev version to get non-default targets
|
||||||
|
# https://github.com/tauri-apps/tauri-action/issues/356
|
||||||
|
- uses: tauri-apps/tauri-action@dev
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
||||||
|
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
||||||
|
ENABLE_CODE_SIGNING: ${{ secrets.APPLE_CERTIFICATE }}
|
||||||
|
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
|
||||||
|
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
||||||
|
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
|
||||||
|
APPLE_ID: ${{ secrets.APPLE_ID }}
|
||||||
|
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
||||||
|
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
|
||||||
|
with:
|
||||||
|
tagName: 'v__VERSION__'
|
||||||
|
releaseName: 'Release __VERSION__'
|
||||||
|
releaseBody: '<!-- Release Notes -->'
|
||||||
|
releaseDraft: true
|
||||||
|
prerelease: false
|
||||||
|
args: '--target ${{ matrix.target }}'
|
||||||
30
.github/workflows/ci.yml
vendored
@@ -1,30 +0,0 @@
|
|||||||
on:
|
|
||||||
pull_request:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
|
|
||||||
name: Lint and Test
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
test:
|
|
||||||
name: Lint/Test
|
|
||||||
runs-on: macos-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
- uses: actions/setup-node@v4
|
|
||||||
- uses: dtolnay/rust-toolchain@stable
|
|
||||||
- uses: Swatinem/rust-cache@v2
|
|
||||||
with:
|
|
||||||
shared-key: ci
|
|
||||||
cache-on-failure: true
|
|
||||||
|
|
||||||
- run: npm ci
|
|
||||||
- run: npm run bootstrap
|
|
||||||
- run: npm run lint
|
|
||||||
- name: Run JS Tests
|
|
||||||
run: npm test
|
|
||||||
- name: Run Rust Tests
|
|
||||||
run: cargo test --all
|
|
||||||
50
.github/workflows/claude.yml
vendored
@@ -1,50 +0,0 @@
|
|||||||
name: Claude Code
|
|
||||||
|
|
||||||
on:
|
|
||||||
issue_comment:
|
|
||||||
types: [created]
|
|
||||||
pull_request_review_comment:
|
|
||||||
types: [created]
|
|
||||||
issues:
|
|
||||||
types: [opened, assigned]
|
|
||||||
pull_request_review:
|
|
||||||
types: [submitted]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
claude:
|
|
||||||
if: |
|
|
||||||
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
|
|
||||||
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
|
|
||||||
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
|
|
||||||
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
pull-requests: read
|
|
||||||
issues: read
|
|
||||||
id-token: write
|
|
||||||
actions: read # Required for Claude to read CI results on PRs
|
|
||||||
steps:
|
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 1
|
|
||||||
|
|
||||||
- name: Run Claude Code
|
|
||||||
id: claude
|
|
||||||
uses: anthropics/claude-code-action@v1
|
|
||||||
with:
|
|
||||||
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
|
||||||
|
|
||||||
# This is an optional setting that allows Claude to read CI results on PRs
|
|
||||||
additional_permissions: |
|
|
||||||
actions: read
|
|
||||||
|
|
||||||
# Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it.
|
|
||||||
# prompt: 'Update the pull request description to include a summary of changes.'
|
|
||||||
|
|
||||||
# Optional: Add claude_args to customize behavior and configuration
|
|
||||||
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
|
|
||||||
# or https://code.claude.com/docs/en/cli-reference for available options
|
|
||||||
# claude_args: '--allowed-tools Bash(gh pr:*)'
|
|
||||||
|
|
||||||
155
.github/workflows/release.yml
vendored
@@ -1,155 +0,0 @@
|
|||||||
name: Generate Artifacts
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
tags: [v*]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build-artifacts:
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
|
|
||||||
name: Build
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
- platform: "macos-latest" # for Arm-based Macs (M1 and above).
|
|
||||||
args: "--target aarch64-apple-darwin"
|
|
||||||
yaak_arch: "arm64"
|
|
||||||
os: "macos"
|
|
||||||
targets: "aarch64-apple-darwin"
|
|
||||||
- platform: "macos-latest" # for Intel-based Macs.
|
|
||||||
args: "--target x86_64-apple-darwin"
|
|
||||||
yaak_arch: "x64"
|
|
||||||
os: "macos"
|
|
||||||
targets: "x86_64-apple-darwin"
|
|
||||||
- platform: "ubuntu-22.04"
|
|
||||||
args: ""
|
|
||||||
yaak_arch: "x64"
|
|
||||||
os: "ubuntu"
|
|
||||||
targets: ""
|
|
||||||
- platform: "ubuntu-22.04-arm"
|
|
||||||
args: ""
|
|
||||||
yaak_arch: "arm64"
|
|
||||||
os: "ubuntu"
|
|
||||||
targets: ""
|
|
||||||
- platform: "windows-latest"
|
|
||||||
args: ""
|
|
||||||
yaak_arch: "x64"
|
|
||||||
os: "windows"
|
|
||||||
targets: ""
|
|
||||||
# Windows ARM64
|
|
||||||
- platform: "windows-latest"
|
|
||||||
args: "--target aarch64-pc-windows-msvc"
|
|
||||||
yaak_arch: "arm64"
|
|
||||||
os: "windows"
|
|
||||||
targets: "aarch64-pc-windows-msvc"
|
|
||||||
runs-on: ${{ matrix.platform }}
|
|
||||||
timeout-minutes: 40
|
|
||||||
steps:
|
|
||||||
- name: Checkout yaakapp/app
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Setup Node
|
|
||||||
uses: actions/setup-node@v4
|
|
||||||
|
|
||||||
- name: install Rust stable
|
|
||||||
uses: dtolnay/rust-toolchain@stable
|
|
||||||
with:
|
|
||||||
targets: ${{ matrix.targets }}
|
|
||||||
|
|
||||||
- uses: Swatinem/rust-cache@v2
|
|
||||||
with:
|
|
||||||
shared-key: ci
|
|
||||||
cache-on-failure: true
|
|
||||||
|
|
||||||
- name: install dependencies (Linux only)
|
|
||||||
if: matrix.os == 'ubuntu'
|
|
||||||
run: |
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf xdg-utils
|
|
||||||
|
|
||||||
- name: Install Protoc for plugin-runtime
|
|
||||||
uses: arduino/setup-protoc@v3
|
|
||||||
with:
|
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
- name: Install trusted-signing-cli (Windows only)
|
|
||||||
if: matrix.os == 'windows'
|
|
||||||
shell: pwsh
|
|
||||||
run: |
|
|
||||||
$ErrorActionPreference = 'Stop'
|
|
||||||
$dir = "$env:USERPROFILE\trusted-signing"
|
|
||||||
New-Item -ItemType Directory -Force -Path $dir | Out-Null
|
|
||||||
$url = "https://github.com/Levminer/trusted-signing-cli/releases/download/0.8.0/trusted-signing-cli.exe"
|
|
||||||
$exe = Join-Path $dir "trusted-signing-cli.exe"
|
|
||||||
Invoke-WebRequest -Uri $url -OutFile $exe
|
|
||||||
echo $dir >> $env:GITHUB_PATH
|
|
||||||
& $exe --version
|
|
||||||
|
|
||||||
- run: npm ci
|
|
||||||
- run: npm run bootstrap
|
|
||||||
env:
|
|
||||||
YAAK_TARGET_ARCH: ${{ matrix.yaak_arch }}
|
|
||||||
- run: npm run lint
|
|
||||||
- name: Run JS Tests
|
|
||||||
run: npm test
|
|
||||||
- name: Run Rust Tests
|
|
||||||
run: cargo test --all
|
|
||||||
|
|
||||||
- name: Set version
|
|
||||||
run: npm run replace-version
|
|
||||||
env:
|
|
||||||
YAAK_VERSION: ${{ github.ref_name }}
|
|
||||||
|
|
||||||
- name: Sign vendored binaries (macOS only)
|
|
||||||
if: matrix.os == 'macos'
|
|
||||||
env:
|
|
||||||
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
|
|
||||||
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
|
||||||
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
|
|
||||||
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
|
|
||||||
run: |
|
|
||||||
# Create keychain
|
|
||||||
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
|
|
||||||
security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
|
|
||||||
security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
|
|
||||||
security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
|
|
||||||
|
|
||||||
# Import certificate
|
|
||||||
echo "$APPLE_CERTIFICATE" | base64 --decode > certificate.p12
|
|
||||||
security import certificate.p12 -P "$APPLE_CERTIFICATE_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
|
|
||||||
security list-keychain -d user -s $KEYCHAIN_PATH
|
|
||||||
|
|
||||||
# Sign vendored binaries with hardened runtime and their specific entitlements
|
|
||||||
codesign --force --options runtime --entitlements crates-tauri/yaak-app/macos/entitlements.yaakprotoc.plist --sign "$APPLE_SIGNING_IDENTITY" crates-tauri/yaak-app/vendored/protoc/yaakprotoc || true
|
|
||||||
codesign --force --options runtime --entitlements crates-tauri/yaak-app/macos/entitlements.yaaknode.plist --sign "$APPLE_SIGNING_IDENTITY" crates-tauri/yaak-app/vendored/node/yaaknode || true
|
|
||||||
|
|
||||||
- uses: tauri-apps/tauri-action@v0
|
|
||||||
env:
|
|
||||||
YAAK_TARGET_ARCH: ${{ matrix.yaak_arch }}
|
|
||||||
|
|
||||||
ENABLE_CODE_SIGNING: ${{ secrets.APPLE_CERTIFICATE }}
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
|
||||||
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
|
||||||
|
|
||||||
# Apple signing stuff
|
|
||||||
APPLE_CERTIFICATE: ${{ matrix.os == 'macos' && secrets.APPLE_CERTIFICATE }}
|
|
||||||
APPLE_CERTIFICATE_PASSWORD: ${{ matrix.os == 'macos' && secrets.APPLE_CERTIFICATE_PASSWORD }}
|
|
||||||
APPLE_ID: ${{ matrix.os == 'macos' && secrets.APPLE_ID }}
|
|
||||||
APPLE_PASSWORD: ${{ matrix.os == 'macos' && secrets.APPLE_PASSWORD }}
|
|
||||||
APPLE_SIGNING_IDENTITY: ${{ matrix.os == 'macos' && secrets.APPLE_SIGNING_IDENTITY }}
|
|
||||||
APPLE_TEAM_ID: ${{ matrix.os == 'macos' && secrets.APPLE_TEAM_ID }}
|
|
||||||
|
|
||||||
# Windows signing stuff
|
|
||||||
AZURE_CLIENT_ID: ${{ matrix.os == 'windows' && secrets.AZURE_CLIENT_ID }}
|
|
||||||
AZURE_CLIENT_SECRET: ${{ matrix.os == 'windows' && secrets.AZURE_CLIENT_SECRET }}
|
|
||||||
AZURE_TENANT_ID: ${{ matrix.os == 'windows' && secrets.AZURE_TENANT_ID }}
|
|
||||||
with:
|
|
||||||
tagName: "v__VERSION__"
|
|
||||||
releaseName: "Release __VERSION__"
|
|
||||||
releaseBody: "[Changelog __VERSION__](https://yaak.app/blog/__VERSION__)"
|
|
||||||
releaseDraft: true
|
|
||||||
prerelease: true
|
|
||||||
args: "${{ matrix.args }} --config ./crates-tauri/yaak-app/tauri.release.conf.json"
|
|
||||||
44
.github/workflows/sponsors.yml
vendored
@@ -1,44 +0,0 @@
|
|||||||
name: Generate Sponsors README
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
schedule:
|
|
||||||
- cron: 30 15 * * 0-6
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
jobs:
|
|
||||||
deploy:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout 🛎️
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- name: Generate Sponsors
|
|
||||||
uses: JamesIves/github-sponsors-readme-action@v1
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.SPONSORS_PAT }}
|
|
||||||
file: 'README.md'
|
|
||||||
maximum: 1999
|
|
||||||
template: '<a href="https://github.com/{{{ login }}}"><img src="{{{ avatarUrl }}}" width="50px" alt="User avatar: {{{ login }}}" /></a> '
|
|
||||||
active-only: false
|
|
||||||
include-private: true
|
|
||||||
marker: 'sponsors-base'
|
|
||||||
|
|
||||||
- name: Generate Sponsors
|
|
||||||
uses: JamesIves/github-sponsors-readme-action@v1
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.SPONSORS_PAT }}
|
|
||||||
file: 'README.md'
|
|
||||||
minimum: 2000
|
|
||||||
template: '<a href="https://github.com/{{{ login }}}"><img src="{{{ avatarUrl }}}" width="80px" alt="User avatar: {{{ login }}}" /></a> '
|
|
||||||
active-only: false
|
|
||||||
include-private: true
|
|
||||||
marker: 'sponsors-premium'
|
|
||||||
|
|
||||||
# ⚠️ Note: You can use any deployment step here to automatically push the README
|
|
||||||
# changes back to your branch.
|
|
||||||
- name: Commit Changes
|
|
||||||
uses: JamesIves/github-pages-deploy-action@v4
|
|
||||||
with:
|
|
||||||
branch: main
|
|
||||||
force: false
|
|
||||||
folder: '.'
|
|
||||||
20
.gitignore
vendored
@@ -15,8 +15,6 @@ dist-ssr
|
|||||||
# Editor directories and files
|
# Editor directories and files
|
||||||
.vscode/*
|
.vscode/*
|
||||||
!.vscode/extensions.json
|
!.vscode/extensions.json
|
||||||
!.vscode/settings.json
|
|
||||||
!.vscode/launch.json
|
|
||||||
.idea
|
.idea
|
||||||
.DS_Store
|
.DS_Store
|
||||||
*.suo
|
*.suo
|
||||||
@@ -24,23 +22,5 @@ dist-ssr
|
|||||||
*.njsproj
|
*.njsproj
|
||||||
*.sln
|
*.sln
|
||||||
*.sw?
|
*.sw?
|
||||||
.eslintcache
|
|
||||||
out
|
|
||||||
|
|
||||||
*.sqlite
|
*.sqlite
|
||||||
*.sqlite-*
|
|
||||||
|
|
||||||
.cargo
|
|
||||||
|
|
||||||
.tmp
|
|
||||||
tmp
|
|
||||||
.zed
|
|
||||||
codebook.toml
|
|
||||||
target
|
|
||||||
|
|
||||||
# Per-worktree Tauri config (generated by post-checkout hook)
|
|
||||||
crates-tauri/yaak-app/tauri.worktree.conf.json
|
|
||||||
|
|
||||||
# Tauri auto-generated permission files
|
|
||||||
**/permissions/autogenerated
|
|
||||||
**/permissions/schemas
|
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
node scripts/git-hooks/post-checkout.mjs "$@"
|
|
||||||
3
.prettierignore
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
node_modules/
|
||||||
|
dist/
|
||||||
|
.prettierrc.cjs
|
||||||
8
.prettierrc.cjs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
module.exports = {
|
||||||
|
"trailingComma": "all",
|
||||||
|
"tabWidth": 2,
|
||||||
|
"semi": true,
|
||||||
|
"singleQuote": true,
|
||||||
|
"printWidth": 100,
|
||||||
|
"bracketSpacing": true
|
||||||
|
}
|
||||||
12
.run/Dev Desktop.run.xml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<component name="ProjectRunConfigurationManager">
|
||||||
|
<configuration default="false" name="Dev Desktop" type="js.build_tools.npm">
|
||||||
|
<package-json value="$PROJECT_DIR$/package.json" />
|
||||||
|
<command value="run" />
|
||||||
|
<scripts>
|
||||||
|
<script value="tauri-dev" />
|
||||||
|
</scripts>
|
||||||
|
<node-interpreter value="project" />
|
||||||
|
<envs />
|
||||||
|
<method v="2" />
|
||||||
|
</configuration>
|
||||||
|
</component>
|
||||||
3
.vscode/extensions.json
vendored
@@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"recommendations": ["biomejs.biome", "rust-lang.rust-analyzer", "bradlc.vscode-tailwindcss"]
|
|
||||||
}
|
|
||||||
26
.vscode/launch.json
vendored
@@ -1,26 +0,0 @@
|
|||||||
{
|
|
||||||
"version": "0.2.0",
|
|
||||||
"configurations": [
|
|
||||||
{
|
|
||||||
"type": "node",
|
|
||||||
"request": "launch",
|
|
||||||
"name": "Dev App",
|
|
||||||
"runtimeExecutable": "npm",
|
|
||||||
"runtimeArgs": ["run", "start"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "node",
|
|
||||||
"request": "launch",
|
|
||||||
"name": "Build App",
|
|
||||||
"runtimeExecutable": "npm",
|
|
||||||
"runtimeArgs": ["run", "start"]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "node",
|
|
||||||
"request": "launch",
|
|
||||||
"name": "Bootstrap",
|
|
||||||
"runtimeExecutable": "npm",
|
|
||||||
"runtimeArgs": ["run", "bootstrap"]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
6
.vscode/settings.json
vendored
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"editor.defaultFormatter": "biomejs.biome",
|
|
||||||
"editor.formatOnSave": true,
|
|
||||||
"biome.enabled": true,
|
|
||||||
"biome.lint.format.enable": true
|
|
||||||
}
|
|
||||||
8669
Cargo.lock
generated
69
Cargo.toml
@@ -1,69 +0,0 @@
|
|||||||
[workspace]
|
|
||||||
resolver = "2"
|
|
||||||
members = [
|
|
||||||
# Shared crates (no Tauri dependency)
|
|
||||||
"crates/yaak-core",
|
|
||||||
"crates/yaak-common",
|
|
||||||
"crates/yaak-crypto",
|
|
||||||
"crates/yaak-git",
|
|
||||||
"crates/yaak-grpc",
|
|
||||||
"crates/yaak-http",
|
|
||||||
"crates/yaak-models",
|
|
||||||
"crates/yaak-plugins",
|
|
||||||
"crates/yaak-sse",
|
|
||||||
"crates/yaak-sync",
|
|
||||||
"crates/yaak-templates",
|
|
||||||
"crates/yaak-tls",
|
|
||||||
"crates/yaak-ws",
|
|
||||||
# CLI crates
|
|
||||||
"crates-cli/yaak-cli",
|
|
||||||
# Tauri-specific crates
|
|
||||||
"crates-tauri/yaak-app",
|
|
||||||
"crates-tauri/yaak-fonts",
|
|
||||||
"crates-tauri/yaak-license",
|
|
||||||
"crates-tauri/yaak-mac-window",
|
|
||||||
"crates-tauri/yaak-tauri-utils",
|
|
||||||
]
|
|
||||||
|
|
||||||
[workspace.dependencies]
|
|
||||||
chrono = "0.4.42"
|
|
||||||
hex = "0.4.3"
|
|
||||||
keyring = "3.6.3"
|
|
||||||
log = "0.4.29"
|
|
||||||
reqwest = "0.12.20"
|
|
||||||
rustls = { version = "0.23.34", default-features = false }
|
|
||||||
rustls-platform-verifier = "0.6.2"
|
|
||||||
serde = "1.0.228"
|
|
||||||
serde_json = "1.0.145"
|
|
||||||
sha2 = "0.10.9"
|
|
||||||
tauri = "2.9.5"
|
|
||||||
tauri-plugin = "2.5.2"
|
|
||||||
tauri-plugin-dialog = "2.4.2"
|
|
||||||
tauri-plugin-shell = "2.3.3"
|
|
||||||
thiserror = "2.0.17"
|
|
||||||
tokio = "1.48.0"
|
|
||||||
ts-rs = "11.1.0"
|
|
||||||
|
|
||||||
# Internal crates - shared
|
|
||||||
yaak-core = { path = "crates/yaak-core" }
|
|
||||||
yaak-common = { path = "crates/yaak-common" }
|
|
||||||
yaak-crypto = { path = "crates/yaak-crypto" }
|
|
||||||
yaak-git = { path = "crates/yaak-git" }
|
|
||||||
yaak-grpc = { path = "crates/yaak-grpc" }
|
|
||||||
yaak-http = { path = "crates/yaak-http" }
|
|
||||||
yaak-models = { path = "crates/yaak-models" }
|
|
||||||
yaak-plugins = { path = "crates/yaak-plugins" }
|
|
||||||
yaak-sse = { path = "crates/yaak-sse" }
|
|
||||||
yaak-sync = { path = "crates/yaak-sync" }
|
|
||||||
yaak-templates = { path = "crates/yaak-templates" }
|
|
||||||
yaak-tls = { path = "crates/yaak-tls" }
|
|
||||||
yaak-ws = { path = "crates/yaak-ws" }
|
|
||||||
|
|
||||||
# Internal crates - Tauri-specific
|
|
||||||
yaak-fonts = { path = "crates-tauri/yaak-fonts" }
|
|
||||||
yaak-license = { path = "crates-tauri/yaak-license" }
|
|
||||||
yaak-mac-window = { path = "crates-tauri/yaak-mac-window" }
|
|
||||||
yaak-tauri-utils = { path = "crates-tauri/yaak-tauri-utils" }
|
|
||||||
|
|
||||||
[profile.release]
|
|
||||||
strip = false
|
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
# Developer Setup
|
|
||||||
|
|
||||||
Yaak is a combined Node.js and Rust monorepo. It is a [Tauri](https://tauri.app) project, so
|
|
||||||
uses Rust and HTML/CSS/JS for the main application but there is also a plugin system powered
|
|
||||||
by a Node.js sidecar that communicates to the app over gRPC.
|
|
||||||
|
|
||||||
Because of the moving parts, there are a few setup steps required before development can
|
|
||||||
begin.
|
|
||||||
|
|
||||||
## Prerequisites
|
|
||||||
|
|
||||||
Make sure you have the following tools installed:
|
|
||||||
|
|
||||||
- [Node.js](https://nodejs.org/en/download/package-manager)
|
|
||||||
- [Rust](https://www.rust-lang.org/tools/install)
|
|
||||||
|
|
||||||
Check the installations with the following commands:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
node -v
|
|
||||||
npm -v
|
|
||||||
rustc --version
|
|
||||||
```
|
|
||||||
|
|
||||||
Install the NPM dependencies:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
npm install
|
|
||||||
```
|
|
||||||
|
|
||||||
Run the `bootstrap` command to do some initial setup:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
npm run bootstrap
|
|
||||||
```
|
|
||||||
|
|
||||||
## Run the App
|
|
||||||
|
|
||||||
After bootstrapping, start the app in development mode:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
npm start
|
|
||||||
```
|
|
||||||
|
|
||||||
## SQLite Migrations
|
|
||||||
|
|
||||||
New migrations can be created from the `src-tauri/` directory:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
npm run migration
|
|
||||||
```
|
|
||||||
|
|
||||||
Rerun the app to apply the migrations.
|
|
||||||
|
|
||||||
_Note: For safety, development builds use a separate database location from production builds._
|
|
||||||
|
|
||||||
## Lezer Grammar Generation
|
|
||||||
|
|
||||||
```sh
|
|
||||||
# Example
|
|
||||||
lezer-generator components/core/Editor/<LANG>/<LANG>.grammar > components/core/Editor/<LANG>/<LANG>.ts
|
|
||||||
```
|
|
||||||
|
|
||||||
## Linting & Formatting
|
|
||||||
|
|
||||||
This repo uses Biome for linting and formatting (replacing ESLint + Prettier).
|
|
||||||
|
|
||||||
- Lint the entire repo:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npm run lint
|
|
||||||
```
|
|
||||||
|
|
||||||
- Auto-fix lint issues where possible:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npm run lint:fix
|
|
||||||
```
|
|
||||||
|
|
||||||
- Format code:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npm run format
|
|
||||||
```
|
|
||||||
|
|
||||||
Notes:
|
|
||||||
- Many workspace packages also expose the same scripts (`lint`, `lint:fix`, and `format`).
|
|
||||||
- TypeScript type-checking still runs separately via `tsc --noEmit` in relevant packages.
|
|
||||||
21
LICENSE
@@ -1,21 +0,0 @@
|
|||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2024 Yaak
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
# MCP Client Plan
|
|
||||||
|
|
||||||
## Goal
|
|
||||||
Add an MCP client mode to Yaak so users can connect to and debug MCP servers.
|
|
||||||
|
|
||||||
## Core Design
|
|
||||||
- **Protocol layer:** Implement JSON‑RPC framing, message IDs, and notifications as the common core.
|
|
||||||
- **Transport interface:** Define an async trait with `connect`, `send`, `receive`, and `close` methods.
|
|
||||||
- **Transports:**
|
|
||||||
- Start with **Standard I/O** for local development.
|
|
||||||
- Reuse the existing HTTP stack for **HTTP streaming** next.
|
|
||||||
- Leave hooks for **WebSocket** support later.
|
|
||||||
|
|
||||||
## Integration
|
|
||||||
- Register MCP as a new request type alongside REST, GraphQL, gRPC, and WebSocket.
|
|
||||||
- Allow per‑request transport selection (stdio or HTTP).
|
|
||||||
- Map inbound messages into a new MCP response model that feeds existing timeline and debug views.
|
|
||||||
|
|
||||||
## Testing and Dog‑fooding
|
|
||||||
- Convert Yaak's own MCP server to Standard I/O for local testing.
|
|
||||||
- Use it internally to validate protocol behavior and message flow.
|
|
||||||
- Add unit and integration tests for JSON‑RPC messaging and transport abstractions.
|
|
||||||
|
|
||||||
## Future Refinements
|
|
||||||
- Add WebSocket transport support once core paths are stable.
|
|
||||||
- Extend timelines for protocol‑level visualization layered over raw transport events.
|
|
||||||
- Implement version and capability negotiation between client and server.
|
|
||||||
78
README.md
@@ -1,70 +1,16 @@
|
|||||||
<p align="center">
|
# Yaak Network Toolkit
|
||||||
<a href="https://github.com/JamesIves/github-sponsors-readme-action">
|
|
||||||
<img width="200px" src="https://github.com/mountain-loop/yaak/raw/main/crates-tauri/yaak-app/icons/icon.png">
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h1 align="center">
|
The most fun you'll ever have working with APIs.
|
||||||
💫 Yaak ➟ Desktop API Client 💫
|
|
||||||
</h1>
|
|
||||||
|
|
||||||
<p align="center">
|
## Common Commands
|
||||||
A fast, privacy-first API client for REST, GraphQL, SSE, WebSocket, and gRPC – built with Tauri, Rust, and React.
|
|
||||||
</p>
|
|
||||||
<p align="center">
|
|
||||||
Development is funded by community-purchased <a href="https://yaak.app/pricing">licenses</a>. You can also <a href="https://github.com/sponsors/gschier">become a sponsor</a> to have your logo appear below. 💖
|
|
||||||
</p>
|
|
||||||
<br>
|
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# Start dev app
|
||||||
|
npm run tauri-dev
|
||||||
|
|
||||||
|
# Migration commands
|
||||||
<p align="center">
|
cd src-tauri
|
||||||
<!-- sponsors-premium --><a href="https://github.com/MVST-Solutions"><img src="https://github.com/MVST-Solutions.png" width="80px" alt="User avatar: MVST-Solutions" /></a> <a href="https://github.com/dharsanb"><img src="https://github.com/dharsanb.png" width="80px" alt="User avatar: dharsanb" /></a> <a href="https://github.com/railwayapp"><img src="https://github.com/railwayapp.png" width="80px" alt="User avatar: railwayapp" /></a> <a href="https://github.com/caseyamcl"><img src="https://github.com/caseyamcl.png" width="80px" alt="User avatar: caseyamcl" /></a> <a href="https://github.com/bytebase"><img src="https://github.com/bytebase.png" width="80px" alt="User avatar: bytebase" /></a> <a href="https://github.com/"><img src="https://raw.githubusercontent.com/JamesIves/github-sponsors-readme-action/dev/.github/assets/placeholder.png" width="80px" alt="User avatar: " /></a> <!-- sponsors-premium -->
|
cargo sqlx migrate add <name>
|
||||||
</p>
|
cargo sqlx migrate run --database-url 'sqlite://db.sqlite?mode=rw'
|
||||||
<p align="center">
|
cargo sqlx prepare --database-url 'sqlite://db.sqlite'
|
||||||
<!-- sponsors-base --><a href="https://github.com/seanwash"><img src="https://github.com/seanwash.png" width="50px" alt="User avatar: seanwash" /></a> <a href="https://github.com/jerath"><img src="https://github.com/jerath.png" width="50px" alt="User avatar: jerath" /></a> <a href="https://github.com/itsa-sh"><img src="https://github.com/itsa-sh.png" width="50px" alt="User avatar: itsa-sh" /></a> <a href="https://github.com/dmmulroy"><img src="https://github.com/dmmulroy.png" width="50px" alt="User avatar: dmmulroy" /></a> <a href="https://github.com/timcole"><img src="https://github.com/timcole.png" width="50px" alt="User avatar: timcole" /></a> <a href="https://github.com/VLZH"><img src="https://github.com/VLZH.png" width="50px" alt="User avatar: VLZH" /></a> <a href="https://github.com/terasaka2k"><img src="https://github.com/terasaka2k.png" width="50px" alt="User avatar: terasaka2k" /></a> <a href="https://github.com/andriyor"><img src="https://github.com/andriyor.png" width="50px" alt="User avatar: andriyor" /></a> <a href="https://github.com/majudhu"><img src="https://github.com/majudhu.png" width="50px" alt="User avatar: majudhu" /></a> <a href="https://github.com/axelrindle"><img src="https://github.com/axelrindle.png" width="50px" alt="User avatar: axelrindle" /></a> <a href="https://github.com/jirizverina"><img src="https://github.com/jirizverina.png" width="50px" alt="User avatar: jirizverina" /></a> <a href="https://github.com/chip-well"><img src="https://github.com/chip-well.png" width="50px" alt="User avatar: chip-well" /></a> <a href="https://github.com/GRAYAH"><img src="https://github.com/GRAYAH.png" width="50px" alt="User avatar: GRAYAH" /></a> <a href="https://github.com/flashblaze"><img src="https://github.com/flashblaze.png" width="50px" alt="User avatar: flashblaze" /></a> <!-- sponsors-base -->
|
```
|
||||||
</p>
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
|
|
||||||
## Features
|
|
||||||
|
|
||||||
Yaak is an offline-first API client designed to stay out of your way while giving you everything you need when you need it.
|
|
||||||
Built with [Tauri](https://tauri.app), Rust, and React, it’s fast, lightweight, and private. No telemetry, no VC funding, and no cloud lock-in.
|
|
||||||
|
|
||||||
|
|
||||||
### 🌐 Work with any API
|
|
||||||
|
|
||||||
- Import collections from Postman, Insomnia, OpenAPI, Swagger, or Curl.
|
|
||||||
- Send requests via REST, GraphQL, gRPC, WebSocket, or Server-Sent Events.
|
|
||||||
- Filter and inspect responses with JSONPath or XPath.
|
|
||||||
|
|
||||||
### 🔐 Stay secure
|
|
||||||
- Use OAuth 2.0, JWT, Basic Auth, or custom plugins for authentication.
|
|
||||||
- Secure sensitive values with encrypted secrets.
|
|
||||||
- Store secrets in your OS keychain.
|
|
||||||
|
|
||||||
### ☁️ Organize & collaborate
|
|
||||||
- Group requests into workspaces and nested folders.
|
|
||||||
- Use environment variables to switch between dev, staging, and prod.
|
|
||||||
- Mirror workspaces to your filesystem for versioning in Git or syncing with Dropbox.
|
|
||||||
|
|
||||||
### 🧩 Extend & customize
|
|
||||||
- Insert dynamic values like UUIDs or timestamps with template tags.
|
|
||||||
- Pick from built-in themes or build your own.
|
|
||||||
- Create plugins to extend authentication, template tags, or the UI.
|
|
||||||
|
|
||||||
|
|
||||||
## Contribution Policy
|
|
||||||
|
|
||||||
Yaak is open source but only accepting contributions for bug fixes. To get started,
|
|
||||||
visit [`DEVELOPMENT.md`](DEVELOPMENT.md) for tips on setting up your environment.
|
|
||||||
|
|
||||||
## Useful Resources
|
|
||||||
|
|
||||||
- [Feedback and Bug Reports](https://feedback.yaak.app)
|
|
||||||
- [Documentation](https://yaak.app/docs)
|
|
||||||
- [Yaak vs Postman](https://yaak.app/alternatives/postman)
|
|
||||||
- [Yaak vs Bruno](https://yaak.app/alternatives/bruno)
|
|
||||||
- [Yaak vs Insomnia](https://yaak.app/alternatives/insomnia)
|
|
||||||
|
|||||||
53
biome.json
@@ -1,53 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "https://biomejs.dev/schemas/2.3.11/schema.json",
|
|
||||||
"linter": {
|
|
||||||
"enabled": true,
|
|
||||||
"rules": {
|
|
||||||
"recommended": true,
|
|
||||||
"a11y": {
|
|
||||||
"useKeyWithClickEvents": "off"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"formatter": {
|
|
||||||
"enabled": true,
|
|
||||||
"indentStyle": "space",
|
|
||||||
"indentWidth": 2,
|
|
||||||
"lineWidth": 100,
|
|
||||||
"bracketSpacing": true
|
|
||||||
},
|
|
||||||
"css": {
|
|
||||||
"parser": {
|
|
||||||
"tailwindDirectives": true
|
|
||||||
},
|
|
||||||
"linter": {
|
|
||||||
"enabled": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"javascript": {
|
|
||||||
"formatter": {
|
|
||||||
"quoteStyle": "single",
|
|
||||||
"jsxQuoteStyle": "double",
|
|
||||||
"trailingCommas": "all",
|
|
||||||
"semicolons": "always"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"files": {
|
|
||||||
"includes": [
|
|
||||||
"**",
|
|
||||||
"!**/node_modules",
|
|
||||||
"!**/dist",
|
|
||||||
"!**/build",
|
|
||||||
"!target",
|
|
||||||
"!scripts",
|
|
||||||
"!crates",
|
|
||||||
"!crates-tauri",
|
|
||||||
"!src-web/tailwind.config.cjs",
|
|
||||||
"!src-web/postcss.config.cjs",
|
|
||||||
"!src-web/vite.config.ts",
|
|
||||||
"!src-web/routeTree.gen.ts",
|
|
||||||
"!packages/plugin-runtime-types/lib",
|
|
||||||
"!**/bindings"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "yaak-cli"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2024"
|
|
||||||
publish = false
|
|
||||||
|
|
||||||
[[bin]]
|
|
||||||
name = "yaakcli"
|
|
||||||
path = "src/main.rs"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
clap = { version = "4", features = ["derive"] }
|
|
||||||
dirs = "6"
|
|
||||||
env_logger = "0.11"
|
|
||||||
log = { workspace = true }
|
|
||||||
serde_json = { workspace = true }
|
|
||||||
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
|
|
||||||
yaak-crypto = { workspace = true }
|
|
||||||
yaak-http = { workspace = true }
|
|
||||||
yaak-models = { workspace = true }
|
|
||||||
yaak-plugins = { workspace = true }
|
|
||||||
yaak-templates = { workspace = true }
|
|
||||||
@@ -1,198 +0,0 @@
|
|||||||
# CLI Command Architecture Plan
|
|
||||||
|
|
||||||
## Goal
|
|
||||||
|
|
||||||
Redesign the yaak-cli command structure to use a resource-oriented `<resource> <action>`
|
|
||||||
pattern that scales well, is discoverable, and supports both human and LLM workflows.
|
|
||||||
|
|
||||||
## Command Architecture
|
|
||||||
|
|
||||||
### Design Principles
|
|
||||||
|
|
||||||
- **Resource-oriented**: top-level commands are nouns, subcommands are verbs
|
|
||||||
- **Polymorphic requests**: `request` covers HTTP, gRPC, and WebSocket — the CLI
|
|
||||||
resolves the type via `get_any_request` and adapts behavior accordingly
|
|
||||||
- **Simple creation, full-fidelity via JSON**: human-friendly flags for basic creation,
|
|
||||||
`--json` for full control (targeted at LLM and scripting workflows)
|
|
||||||
- **Runtime schema introspection**: `request schema` outputs JSON Schema for the request
|
|
||||||
models, with dynamic auth fields populated from loaded plugins at runtime
|
|
||||||
- **Destructive actions require confirmation**: `delete` commands prompt for user
|
|
||||||
confirmation before proceeding. Can be bypassed with `--yes` / `-y` for scripting
|
|
||||||
|
|
||||||
### Commands
|
|
||||||
|
|
||||||
```
|
|
||||||
# Top-level shortcut
|
|
||||||
yaakcli send <id> [-e <env_id>] # id can be a request, folder, or workspace
|
|
||||||
|
|
||||||
# Resource commands
|
|
||||||
yaakcli workspace list
|
|
||||||
yaakcli workspace show <id>
|
|
||||||
yaakcli workspace create --name <name>
|
|
||||||
yaakcli workspace create --json '{"name": "My Workspace"}'
|
|
||||||
yaakcli workspace create '{"name": "My Workspace"}' # positional JSON shorthand
|
|
||||||
yaakcli workspace update --json '{"id": "wk_abc", "name": "New Name"}'
|
|
||||||
yaakcli workspace delete <id>
|
|
||||||
|
|
||||||
yaakcli request list <workspace_id>
|
|
||||||
yaakcli request show <id>
|
|
||||||
yaakcli request create <workspace_id> --name <name> --url <url> [--method GET]
|
|
||||||
yaakcli request create --json '{"workspaceId": "wk_abc", "url": "..."}'
|
|
||||||
yaakcli request update --json '{"id": "rq_abc", "url": "https://new.com"}'
|
|
||||||
yaakcli request send <id> [-e <env_id>]
|
|
||||||
yaakcli request delete <id>
|
|
||||||
yaakcli request schema <http|grpc|websocket>
|
|
||||||
|
|
||||||
yaakcli folder list <workspace_id>
|
|
||||||
yaakcli folder show <id>
|
|
||||||
yaakcli folder create <workspace_id> --name <name>
|
|
||||||
yaakcli folder create --json '{"workspaceId": "wk_abc", "name": "Auth"}'
|
|
||||||
yaakcli folder update --json '{"id": "fl_abc", "name": "New Name"}'
|
|
||||||
yaakcli folder delete <id>
|
|
||||||
|
|
||||||
yaakcli environment list <workspace_id>
|
|
||||||
yaakcli environment show <id>
|
|
||||||
yaakcli environment create <workspace_id> --name <name>
|
|
||||||
yaakcli environment create --json '{"workspaceId": "wk_abc", "name": "Production"}'
|
|
||||||
yaakcli environment update --json '{"id": "ev_abc", ...}'
|
|
||||||
yaakcli environment delete <id>
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
### `send` — Top-Level Shortcut
|
|
||||||
|
|
||||||
`yaakcli send <id>` is a convenience alias that accepts any sendable ID. It tries
|
|
||||||
each type in order via DB lookups (short-circuiting on first match):
|
|
||||||
|
|
||||||
1. Request (HTTP, gRPC, or WebSocket via `get_any_request`)
|
|
||||||
2. Folder (sends all requests in the folder)
|
|
||||||
3. Workspace (sends all requests in the workspace)
|
|
||||||
|
|
||||||
ID prefixes exist (e.g. `rq_`, `fl_`, `wk_`) but are not relied upon — resolution
|
|
||||||
is purely by DB lookup.
|
|
||||||
|
|
||||||
`request send <id>` is the same but restricted to request IDs only.
|
|
||||||
|
|
||||||
### Request Send — Polymorphic Behavior
|
|
||||||
|
|
||||||
`send` means "execute this request" regardless of protocol:
|
|
||||||
|
|
||||||
- **HTTP**: send request, print response, exit
|
|
||||||
- **gRPC**: invoke the method; for streaming, stream output to stdout until done/Ctrl+C
|
|
||||||
- **WebSocket**: connect, stream messages to stdout until closed/Ctrl+C
|
|
||||||
|
|
||||||
### `request schema` — Runtime JSON Schema
|
|
||||||
|
|
||||||
Outputs a JSON Schema describing the full request shape, including dynamic fields:
|
|
||||||
|
|
||||||
1. Generate base schema from `schemars::JsonSchema` derive on the Rust model structs
|
|
||||||
2. Load plugins, collect auth strategy definitions and their form inputs
|
|
||||||
3. Merge plugin-defined auth fields into the `authentication` property as a `oneOf`
|
|
||||||
4. Output the combined schema as JSON
|
|
||||||
|
|
||||||
This lets an LLM call `schema`, read the shape, and construct valid JSON for
|
|
||||||
`create --json` or `update --json`.
|
|
||||||
|
|
||||||
## Implementation Steps
|
|
||||||
|
|
||||||
### Phase 1: Restructure commands (no new functionality)
|
|
||||||
|
|
||||||
Refactor `main.rs` into the new resource/action pattern using clap subcommand nesting.
|
|
||||||
Existing behavior stays the same, just reorganized. Remove the `get` command.
|
|
||||||
|
|
||||||
1. Create module structure: `commands/workspace.rs`, `commands/request.rs`, etc.
|
|
||||||
2. Define nested clap enums:
|
|
||||||
```rust
|
|
||||||
enum Commands {
|
|
||||||
Send(SendArgs),
|
|
||||||
Workspace(WorkspaceArgs),
|
|
||||||
Request(RequestArgs),
|
|
||||||
Folder(FolderArgs),
|
|
||||||
Environment(EnvironmentArgs),
|
|
||||||
}
|
|
||||||
```
|
|
||||||
3. Move existing `Workspaces` logic into `workspace list`
|
|
||||||
4. Move existing `Requests` logic into `request list`
|
|
||||||
5. Move existing `Send` logic into `request send`
|
|
||||||
6. Move existing `Create` logic into `request create`
|
|
||||||
7. Delete the `Get` command entirely
|
|
||||||
8. Extract shared setup (DB init, plugin init, encryption) into a reusable context struct
|
|
||||||
|
|
||||||
### Phase 2: Add missing CRUD commands
|
|
||||||
|
|
||||||
1. `workspace show <id>`
|
|
||||||
2. `workspace create --name <name>` (and `--json`)
|
|
||||||
3. `workspace update --json`
|
|
||||||
4. `workspace delete <id>`
|
|
||||||
5. `request show <id>` (JSON output of the full request model)
|
|
||||||
6. `request delete <id>`
|
|
||||||
7. `folder list <workspace_id>`
|
|
||||||
8. `folder show <id>`
|
|
||||||
9. `folder create <workspace_id> --name <name>` (and `--json`)
|
|
||||||
10. `folder update --json`
|
|
||||||
11. `folder delete <id>`
|
|
||||||
12. `environment list <workspace_id>`
|
|
||||||
13. `environment show <id>`
|
|
||||||
14. `environment create <workspace_id> --name <name>` (and `--json`)
|
|
||||||
15. `environment update --json`
|
|
||||||
16. `environment delete <id>`
|
|
||||||
|
|
||||||
### Phase 3: JSON input for create/update
|
|
||||||
|
|
||||||
Both commands accept JSON via `--json <string>` or as a positional argument (detected
|
|
||||||
by leading `{`). They follow the same upsert pattern as the plugin API.
|
|
||||||
|
|
||||||
- **`create --json`**: JSON must include `workspaceId`. Must NOT include `id` (or
|
|
||||||
use empty string `""`). Deserializes into the model with defaults for missing fields,
|
|
||||||
then upserts (insert).
|
|
||||||
- **`update --json`**: JSON must include `id`. Performs a fetch-merge-upsert:
|
|
||||||
1. Fetch the existing model from DB
|
|
||||||
2. Serialize it to `serde_json::Value`
|
|
||||||
3. Deep-merge the user's partial JSON on top (JSON Merge Patch / RFC 7386 semantics)
|
|
||||||
4. Deserialize back into the typed model
|
|
||||||
5. Upsert (update)
|
|
||||||
|
|
||||||
This matches how the MCP server plugin already does it (fetch existing, spread, override),
|
|
||||||
but the CLI handles the merge server-side so callers don't have to.
|
|
||||||
|
|
||||||
Setting a field to `null` removes it (for `Option<T>` fields), per RFC 7386.
|
|
||||||
|
|
||||||
Implementation:
|
|
||||||
1. Add `--json` flag and positional JSON detection to `create` commands
|
|
||||||
2. Add `update` commands with required `--json` flag
|
|
||||||
3. Implement JSON merge utility (or use `json-patch` crate)
|
|
||||||
|
|
||||||
### Phase 4: Runtime schema generation
|
|
||||||
|
|
||||||
1. Add `schemars` dependency to `yaak-models`
|
|
||||||
2. Derive `JsonSchema` on `HttpRequest`, `GrpcRequest`, `WebsocketRequest`, and their
|
|
||||||
nested types (`HttpRequestHeader`, `HttpUrlParameter`, etc.)
|
|
||||||
3. Implement `request schema` command:
|
|
||||||
- Generate base schema from schemars
|
|
||||||
- Query plugins for auth strategy form inputs
|
|
||||||
- Convert plugin form inputs into JSON Schema properties
|
|
||||||
- Merge into the `authentication` field
|
|
||||||
- Print to stdout
|
|
||||||
|
|
||||||
### Phase 5: Polymorphic send
|
|
||||||
|
|
||||||
1. Update `request send` to use `get_any_request` to resolve the request type
|
|
||||||
2. Match on `AnyRequest` variant and dispatch to the appropriate sender:
|
|
||||||
- `AnyRequest::HttpRequest` — existing HTTP send logic
|
|
||||||
- `AnyRequest::GrpcRequest` — gRPC invoke (future implementation)
|
|
||||||
- `AnyRequest::WebsocketRequest` — WebSocket connect (future implementation)
|
|
||||||
3. gRPC and WebSocket send can initially return "not yet implemented" errors
|
|
||||||
|
|
||||||
### Phase 6: Top-level `send` and folder/workspace send
|
|
||||||
|
|
||||||
1. Add top-level `yaakcli send <id>` command
|
|
||||||
2. Resolve ID by trying DB lookups in order: any_request → folder → workspace
|
|
||||||
3. For folder: list all requests in folder, send each
|
|
||||||
4. For workspace: list all requests in workspace, send each
|
|
||||||
5. Add execution options: `--sequential` (default), `--parallel`, `--fail-fast`
|
|
||||||
|
|
||||||
## Crate Changes
|
|
||||||
|
|
||||||
- **yaak-cli**: restructure into modules, new clap hierarchy
|
|
||||||
- **yaak-models**: add `schemars` dependency, derive `JsonSchema` on model structs
|
|
||||||
(current derives: `Debug, Clone, PartialEq, Serialize, Deserialize, Default, TS`)
|
|
||||||
@@ -1,409 +0,0 @@
|
|||||||
use clap::{Parser, Subcommand};
|
|
||||||
use log::info;
|
|
||||||
use serde_json::Value;
|
|
||||||
use std::collections::BTreeMap;
|
|
||||||
use std::path::PathBuf;
|
|
||||||
use std::sync::Arc;
|
|
||||||
use tokio::sync::mpsc;
|
|
||||||
use yaak_crypto::manager::EncryptionManager;
|
|
||||||
use yaak_http::path_placeholders::apply_path_placeholders;
|
|
||||||
use yaak_http::sender::{HttpSender, ReqwestSender};
|
|
||||||
use yaak_http::types::{SendableHttpRequest, SendableHttpRequestOptions};
|
|
||||||
use yaak_models::models::{HttpRequest, HttpRequestHeader, HttpUrlParameter};
|
|
||||||
use yaak_models::render::make_vars_hashmap;
|
|
||||||
use yaak_models::util::UpdateSource;
|
|
||||||
use yaak_plugins::events::{PluginContext, RenderPurpose};
|
|
||||||
use yaak_plugins::manager::PluginManager;
|
|
||||||
use yaak_plugins::template_callback::PluginTemplateCallback;
|
|
||||||
use yaak_templates::{RenderOptions, parse_and_render, render_json_value_raw};
|
|
||||||
|
|
||||||
#[derive(Parser)]
|
|
||||||
#[command(name = "yaakcli")]
|
|
||||||
#[command(about = "Yaak CLI - API client from the command line")]
|
|
||||||
struct Cli {
|
|
||||||
/// Use a custom data directory
|
|
||||||
#[arg(long, global = true)]
|
|
||||||
data_dir: Option<PathBuf>,
|
|
||||||
|
|
||||||
/// Environment ID to use for variable substitution
|
|
||||||
#[arg(long, short, global = true)]
|
|
||||||
environment: Option<String>,
|
|
||||||
|
|
||||||
/// Enable verbose logging
|
|
||||||
#[arg(long, short, global = true)]
|
|
||||||
verbose: bool,
|
|
||||||
|
|
||||||
#[command(subcommand)]
|
|
||||||
command: Commands,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Subcommand)]
|
|
||||||
enum Commands {
|
|
||||||
/// List all workspaces
|
|
||||||
Workspaces,
|
|
||||||
/// List requests in a workspace
|
|
||||||
Requests {
|
|
||||||
/// Workspace ID
|
|
||||||
workspace_id: String,
|
|
||||||
},
|
|
||||||
/// Send an HTTP request by ID
|
|
||||||
Send {
|
|
||||||
/// Request ID
|
|
||||||
request_id: String,
|
|
||||||
},
|
|
||||||
/// Send a GET request to a URL
|
|
||||||
Get {
|
|
||||||
/// URL to request
|
|
||||||
url: String,
|
|
||||||
},
|
|
||||||
/// Create a new HTTP request
|
|
||||||
Create {
|
|
||||||
/// Workspace ID
|
|
||||||
workspace_id: String,
|
|
||||||
/// Request name
|
|
||||||
#[arg(short, long)]
|
|
||||||
name: String,
|
|
||||||
/// HTTP method
|
|
||||||
#[arg(short, long, default_value = "GET")]
|
|
||||||
method: String,
|
|
||||||
/// URL
|
|
||||||
#[arg(short, long)]
|
|
||||||
url: String,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Render an HTTP request with template variables and plugin functions
|
|
||||||
async fn render_http_request(
|
|
||||||
r: &HttpRequest,
|
|
||||||
environment_chain: Vec<yaak_models::models::Environment>,
|
|
||||||
cb: &PluginTemplateCallback,
|
|
||||||
opt: &RenderOptions,
|
|
||||||
) -> yaak_templates::error::Result<HttpRequest> {
|
|
||||||
let vars = &make_vars_hashmap(environment_chain);
|
|
||||||
|
|
||||||
let mut url_parameters = Vec::new();
|
|
||||||
for p in r.url_parameters.clone() {
|
|
||||||
if !p.enabled {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
url_parameters.push(HttpUrlParameter {
|
|
||||||
enabled: p.enabled,
|
|
||||||
name: parse_and_render(p.name.as_str(), vars, cb, opt).await?,
|
|
||||||
value: parse_and_render(p.value.as_str(), vars, cb, opt).await?,
|
|
||||||
id: p.id,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut headers = Vec::new();
|
|
||||||
for p in r.headers.clone() {
|
|
||||||
if !p.enabled {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
headers.push(HttpRequestHeader {
|
|
||||||
enabled: p.enabled,
|
|
||||||
name: parse_and_render(p.name.as_str(), vars, cb, opt).await?,
|
|
||||||
value: parse_and_render(p.value.as_str(), vars, cb, opt).await?,
|
|
||||||
id: p.id,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut body = BTreeMap::new();
|
|
||||||
for (k, v) in r.body.clone() {
|
|
||||||
body.insert(k, render_json_value_raw(v, vars, cb, opt).await?);
|
|
||||||
}
|
|
||||||
|
|
||||||
let authentication = {
|
|
||||||
let mut disabled = false;
|
|
||||||
let mut auth = BTreeMap::new();
|
|
||||||
match r.authentication.get("disabled") {
|
|
||||||
Some(Value::Bool(true)) => {
|
|
||||||
disabled = true;
|
|
||||||
}
|
|
||||||
Some(Value::String(tmpl)) => {
|
|
||||||
disabled = parse_and_render(tmpl.as_str(), vars, cb, opt)
|
|
||||||
.await
|
|
||||||
.unwrap_or_default()
|
|
||||||
.is_empty();
|
|
||||||
info!(
|
|
||||||
"Rendering authentication.disabled as a template: {disabled} from \"{tmpl}\""
|
|
||||||
);
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
if disabled {
|
|
||||||
auth.insert("disabled".to_string(), Value::Bool(true));
|
|
||||||
} else {
|
|
||||||
for (k, v) in r.authentication.clone() {
|
|
||||||
if k == "disabled" {
|
|
||||||
auth.insert(k, Value::Bool(false));
|
|
||||||
} else {
|
|
||||||
auth.insert(k, render_json_value_raw(v, vars, cb, opt).await?);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
auth
|
|
||||||
};
|
|
||||||
|
|
||||||
let url = parse_and_render(r.url.clone().as_str(), vars, cb, opt).await?;
|
|
||||||
|
|
||||||
// Apply path placeholders (e.g., /users/:id -> /users/123)
|
|
||||||
let (url, url_parameters) = apply_path_placeholders(&url, &url_parameters);
|
|
||||||
|
|
||||||
Ok(HttpRequest { url, url_parameters, headers, body, authentication, ..r.to_owned() })
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::main]
|
|
||||||
async fn main() {
|
|
||||||
let cli = Cli::parse();
|
|
||||||
|
|
||||||
// Initialize logging
|
|
||||||
if cli.verbose {
|
|
||||||
env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use the same app_id for both data directory and keyring
|
|
||||||
let app_id = if cfg!(debug_assertions) { "app.yaak.desktop.dev" } else { "app.yaak.desktop" };
|
|
||||||
|
|
||||||
let data_dir = cli.data_dir.unwrap_or_else(|| {
|
|
||||||
dirs::data_dir().expect("Could not determine data directory").join(app_id)
|
|
||||||
});
|
|
||||||
|
|
||||||
let db_path = data_dir.join("db.sqlite");
|
|
||||||
let blob_path = data_dir.join("blobs.sqlite");
|
|
||||||
|
|
||||||
let (query_manager, _blob_manager, _rx) =
|
|
||||||
yaak_models::init_standalone(&db_path, &blob_path).expect("Failed to initialize database");
|
|
||||||
|
|
||||||
let db = query_manager.connect();
|
|
||||||
|
|
||||||
// Initialize encryption manager for secure() template function
|
|
||||||
// Use the same app_id as the Tauri app for keyring access
|
|
||||||
let encryption_manager = Arc::new(EncryptionManager::new(query_manager.clone(), app_id));
|
|
||||||
|
|
||||||
// Initialize plugin manager for template functions
|
|
||||||
let vendored_plugin_dir = data_dir.join("vendored-plugins");
|
|
||||||
let installed_plugin_dir = data_dir.join("installed-plugins");
|
|
||||||
|
|
||||||
// Use system node for CLI (must be in PATH)
|
|
||||||
let node_bin_path = PathBuf::from("node");
|
|
||||||
|
|
||||||
// Find the plugin runtime - check YAAK_PLUGIN_RUNTIME env var, then fallback to development path
|
|
||||||
let plugin_runtime_main =
|
|
||||||
std::env::var("YAAK_PLUGIN_RUNTIME").map(PathBuf::from).unwrap_or_else(|_| {
|
|
||||||
// Development fallback: look relative to crate root
|
|
||||||
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
|
|
||||||
.join("../../crates-tauri/yaak-app/vendored/plugin-runtime/index.cjs")
|
|
||||||
});
|
|
||||||
|
|
||||||
// Create plugin manager (plugins may not be available in CLI context)
|
|
||||||
let plugin_manager = Arc::new(
|
|
||||||
PluginManager::new(
|
|
||||||
vendored_plugin_dir,
|
|
||||||
installed_plugin_dir,
|
|
||||||
node_bin_path,
|
|
||||||
plugin_runtime_main,
|
|
||||||
false,
|
|
||||||
)
|
|
||||||
.await,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Initialize plugins from database
|
|
||||||
let plugins = db.list_plugins().unwrap_or_default();
|
|
||||||
if !plugins.is_empty() {
|
|
||||||
let errors =
|
|
||||||
plugin_manager.initialize_all_plugins(plugins, &PluginContext::new_empty()).await;
|
|
||||||
for (plugin_dir, error_msg) in errors {
|
|
||||||
eprintln!("Warning: Failed to initialize plugin '{}': {}", plugin_dir, error_msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
match cli.command {
|
|
||||||
Commands::Workspaces => {
|
|
||||||
let workspaces = db.list_workspaces().expect("Failed to list workspaces");
|
|
||||||
if workspaces.is_empty() {
|
|
||||||
println!("No workspaces found");
|
|
||||||
} else {
|
|
||||||
for ws in workspaces {
|
|
||||||
println!("{} - {}", ws.id, ws.name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Commands::Requests { workspace_id } => {
|
|
||||||
let requests = db.list_http_requests(&workspace_id).expect("Failed to list requests");
|
|
||||||
if requests.is_empty() {
|
|
||||||
println!("No requests found in workspace {}", workspace_id);
|
|
||||||
} else {
|
|
||||||
for req in requests {
|
|
||||||
println!("{} - {} {}", req.id, req.method, req.name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Commands::Send { request_id } => {
|
|
||||||
let request = db.get_http_request(&request_id).expect("Failed to get request");
|
|
||||||
|
|
||||||
// Resolve environment chain for variable substitution
|
|
||||||
let environment_chain = db
|
|
||||||
.resolve_environments(
|
|
||||||
&request.workspace_id,
|
|
||||||
request.folder_id.as_deref(),
|
|
||||||
cli.environment.as_deref(),
|
|
||||||
)
|
|
||||||
.unwrap_or_default();
|
|
||||||
|
|
||||||
// Create template callback with plugin support
|
|
||||||
let plugin_context = PluginContext::new(None, Some(request.workspace_id.clone()));
|
|
||||||
let template_callback = PluginTemplateCallback::new(
|
|
||||||
plugin_manager.clone(),
|
|
||||||
encryption_manager.clone(),
|
|
||||||
&plugin_context,
|
|
||||||
RenderPurpose::Send,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Render templates in the request
|
|
||||||
let rendered_request = render_http_request(
|
|
||||||
&request,
|
|
||||||
environment_chain,
|
|
||||||
&template_callback,
|
|
||||||
&RenderOptions::throw(),
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.expect("Failed to render request templates");
|
|
||||||
|
|
||||||
if cli.verbose {
|
|
||||||
println!("> {} {}", rendered_request.method, rendered_request.url);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert to sendable request
|
|
||||||
let sendable = SendableHttpRequest::from_http_request(
|
|
||||||
&rendered_request,
|
|
||||||
SendableHttpRequestOptions::default(),
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.expect("Failed to build request");
|
|
||||||
|
|
||||||
// Create event channel for progress
|
|
||||||
let (event_tx, mut event_rx) = mpsc::channel(100);
|
|
||||||
|
|
||||||
// Spawn task to print events if verbose
|
|
||||||
let verbose = cli.verbose;
|
|
||||||
let verbose_handle = if verbose {
|
|
||||||
Some(tokio::spawn(async move {
|
|
||||||
while let Some(event) = event_rx.recv().await {
|
|
||||||
println!("{}", event);
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
} else {
|
|
||||||
// Drain events silently
|
|
||||||
tokio::spawn(async move { while event_rx.recv().await.is_some() {} });
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
// Send the request
|
|
||||||
let sender = ReqwestSender::new().expect("Failed to create HTTP client");
|
|
||||||
let response = sender.send(sendable, event_tx).await.expect("Failed to send request");
|
|
||||||
|
|
||||||
// Wait for event handler to finish
|
|
||||||
if let Some(handle) = verbose_handle {
|
|
||||||
let _ = handle.await;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Print response
|
|
||||||
if verbose {
|
|
||||||
println!();
|
|
||||||
}
|
|
||||||
println!(
|
|
||||||
"HTTP {} {}",
|
|
||||||
response.status,
|
|
||||||
response.status_reason.as_deref().unwrap_or("")
|
|
||||||
);
|
|
||||||
|
|
||||||
if verbose {
|
|
||||||
for (name, value) in &response.headers {
|
|
||||||
println!("{}: {}", name, value);
|
|
||||||
}
|
|
||||||
println!();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Print body
|
|
||||||
let (body, _stats) = response.text().await.expect("Failed to read response body");
|
|
||||||
println!("{}", body);
|
|
||||||
}
|
|
||||||
Commands::Get { url } => {
|
|
||||||
if cli.verbose {
|
|
||||||
println!("> GET {}", url);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build a simple GET request
|
|
||||||
let sendable = SendableHttpRequest {
|
|
||||||
url: url.clone(),
|
|
||||||
method: "GET".to_string(),
|
|
||||||
headers: vec![],
|
|
||||||
body: None,
|
|
||||||
options: SendableHttpRequestOptions::default(),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Create event channel for progress
|
|
||||||
let (event_tx, mut event_rx) = mpsc::channel(100);
|
|
||||||
|
|
||||||
// Spawn task to print events if verbose
|
|
||||||
let verbose = cli.verbose;
|
|
||||||
let verbose_handle = if verbose {
|
|
||||||
Some(tokio::spawn(async move {
|
|
||||||
while let Some(event) = event_rx.recv().await {
|
|
||||||
println!("{}", event);
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
} else {
|
|
||||||
tokio::spawn(async move { while event_rx.recv().await.is_some() {} });
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
// Send the request
|
|
||||||
let sender = ReqwestSender::new().expect("Failed to create HTTP client");
|
|
||||||
let response = sender.send(sendable, event_tx).await.expect("Failed to send request");
|
|
||||||
|
|
||||||
if let Some(handle) = verbose_handle {
|
|
||||||
let _ = handle.await;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Print response
|
|
||||||
if verbose {
|
|
||||||
println!();
|
|
||||||
}
|
|
||||||
println!(
|
|
||||||
"HTTP {} {}",
|
|
||||||
response.status,
|
|
||||||
response.status_reason.as_deref().unwrap_or("")
|
|
||||||
);
|
|
||||||
|
|
||||||
if verbose {
|
|
||||||
for (name, value) in &response.headers {
|
|
||||||
println!("{}: {}", name, value);
|
|
||||||
}
|
|
||||||
println!();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Print body
|
|
||||||
let (body, _stats) = response.text().await.expect("Failed to read response body");
|
|
||||||
println!("{}", body);
|
|
||||||
}
|
|
||||||
Commands::Create { workspace_id, name, method, url } => {
|
|
||||||
let request = HttpRequest {
|
|
||||||
workspace_id,
|
|
||||||
name,
|
|
||||||
method: method.to_uppercase(),
|
|
||||||
url,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
let created = db
|
|
||||||
.upsert_http_request(&request, &UpdateSource::Sync)
|
|
||||||
.expect("Failed to create request");
|
|
||||||
|
|
||||||
println!("Created request: {}", created.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Terminate plugin manager gracefully
|
|
||||||
plugin_manager.terminate().await;
|
|
||||||
}
|
|
||||||
10
crates-tauri/yaak-app/.gitignore
vendored
@@ -1,10 +0,0 @@
|
|||||||
# Generated by Cargo
|
|
||||||
# will have compiled files and executables
|
|
||||||
target/
|
|
||||||
|
|
||||||
vendored/*
|
|
||||||
|
|
||||||
gen/*
|
|
||||||
|
|
||||||
**/permissions/autogenerated
|
|
||||||
**/permissions/schemas
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "yaak-app"
|
|
||||||
version = "0.0.0"
|
|
||||||
edition = "2024"
|
|
||||||
authors = ["Gregory Schier"]
|
|
||||||
publish = false
|
|
||||||
|
|
||||||
# Produce a library for mobile support
|
|
||||||
[lib]
|
|
||||||
name = "tauri_app_lib"
|
|
||||||
crate-type = ["staticlib", "cdylib", "lib"]
|
|
||||||
|
|
||||||
[features]
|
|
||||||
cargo-clippy = []
|
|
||||||
default = []
|
|
||||||
updater = []
|
|
||||||
license = ["yaak-license"]
|
|
||||||
|
|
||||||
[build-dependencies]
|
|
||||||
tauri-build = { version = "2.5.3", features = [] }
|
|
||||||
|
|
||||||
[target.'cfg(target_os = "linux")'.dependencies]
|
|
||||||
openssl-sys = { version = "0.9.105", features = ["vendored"] } # For Ubuntu installation to work
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
charset = "0.1.5"
|
|
||||||
chrono = { workspace = true, features = ["serde"] }
|
|
||||||
cookie = "0.18.1"
|
|
||||||
eventsource-client = { git = "https://github.com/yaakapp/rust-eventsource-client", version = "0.14.0" }
|
|
||||||
http = { version = "1.2.0", default-features = false }
|
|
||||||
log = { workspace = true }
|
|
||||||
md5 = "0.8.0"
|
|
||||||
r2d2 = "0.8.10"
|
|
||||||
r2d2_sqlite = "0.25.0"
|
|
||||||
mime_guess = "2.0.5"
|
|
||||||
rand = "0.9.0"
|
|
||||||
reqwest = { workspace = true, features = ["multipart", "gzip", "brotli", "deflate", "json", "rustls-tls-manual-roots-no-provider", "socks", "http2"] }
|
|
||||||
serde = { workspace = true, features = ["derive"] }
|
|
||||||
serde_json = { workspace = true, features = ["raw_value"] }
|
|
||||||
tauri = { workspace = true, features = ["devtools", "protocol-asset"] }
|
|
||||||
tauri-plugin-clipboard-manager = "2.3.2"
|
|
||||||
tauri-plugin-deep-link = "2.4.5"
|
|
||||||
tauri-plugin-dialog = { workspace = true }
|
|
||||||
tauri-plugin-fs = "2.4.4"
|
|
||||||
tauri-plugin-log = { version = "2.7.1", features = ["colored"] }
|
|
||||||
tauri-plugin-opener = "2.5.2"
|
|
||||||
tauri-plugin-os = "2.3.2"
|
|
||||||
tauri-plugin-shell = { workspace = true }
|
|
||||||
tauri-plugin-single-instance = { version = "2.3.6", features = ["deep-link"] }
|
|
||||||
tauri-plugin-updater = "2.9.0"
|
|
||||||
tauri-plugin-window-state = "2.4.1"
|
|
||||||
thiserror = { workspace = true }
|
|
||||||
tokio = { workspace = true, features = ["sync"] }
|
|
||||||
tokio-stream = "0.1.17"
|
|
||||||
tokio-tungstenite = { version = "0.26.2", default-features = false }
|
|
||||||
url = "2"
|
|
||||||
tokio-util = { version = "0.7", features = ["codec"] }
|
|
||||||
ts-rs = { workspace = true }
|
|
||||||
uuid = "1.12.1"
|
|
||||||
yaak-common = { workspace = true }
|
|
||||||
yaak-tauri-utils = { workspace = true }
|
|
||||||
yaak-core = { workspace = true }
|
|
||||||
yaak-crypto = { workspace = true }
|
|
||||||
yaak-fonts = { workspace = true }
|
|
||||||
yaak-git = { workspace = true }
|
|
||||||
yaak-grpc = { workspace = true }
|
|
||||||
yaak-http = { workspace = true }
|
|
||||||
yaak-license = { workspace = true, optional = true }
|
|
||||||
yaak-mac-window = { workspace = true }
|
|
||||||
yaak-models = { workspace = true }
|
|
||||||
yaak-plugins = { workspace = true }
|
|
||||||
yaak-sse = { workspace = true }
|
|
||||||
yaak-sync = { workspace = true }
|
|
||||||
yaak-templates = { workspace = true }
|
|
||||||
yaak-tls = { workspace = true }
|
|
||||||
yaak-ws = { workspace = true }
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
|
||||||
|
|
||||||
export type WatchResult = { unlistenEvent: string, };
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
|
||||||
|
|
||||||
export type PluginUpdateInfo = { name: string, currentVersion: string, latestVersion: string, };
|
|
||||||
|
|
||||||
export type PluginUpdateNotification = { updateCount: number, plugins: Array<PluginUpdateInfo>, };
|
|
||||||
|
|
||||||
export type UpdateInfo = { replyEventId: string, version: string, downloaded: boolean, };
|
|
||||||
|
|
||||||
export type UpdateResponse = { "type": "ack" } | { "type": "action", action: UpdateResponseAction, };
|
|
||||||
|
|
||||||
export type UpdateResponseAction = "install" | "skip";
|
|
||||||
|
|
||||||
export type WatchResult = { unlistenEvent: string, };
|
|
||||||
|
|
||||||
export type YaakNotification = { timestamp: string, timeout: number | null, id: string, title: string | null, message: string, color: string | null, action: YaakNotificationAction | null, };
|
|
||||||
|
|
||||||
export type YaakNotificationAction = { label: string, url: string, };
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
|
|
||||||
|
|
||||||
export type PluginUpdateInfo = { name: string, currentVersion: string, latestVersion: string, };
|
|
||||||
|
|
||||||
export type PluginUpdateNotification = { updateCount: number, plugins: Array<PluginUpdateInfo>, };
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
{
|
|
||||||
"identifier": "default",
|
|
||||||
"description": "Default capabilities for all build variants",
|
|
||||||
"windows": [
|
|
||||||
"*"
|
|
||||||
],
|
|
||||||
"permissions": [
|
|
||||||
"core:app:allow-identifier",
|
|
||||||
"core:event:allow-emit",
|
|
||||||
"core:event:allow-listen",
|
|
||||||
"core:event:allow-unlisten",
|
|
||||||
"core:path:allow-resolve-directory",
|
|
||||||
"core:path:allow-basename",
|
|
||||||
"os:allow-os-type",
|
|
||||||
"clipboard-manager:allow-clear",
|
|
||||||
"clipboard-manager:allow-write-text",
|
|
||||||
"clipboard-manager:allow-read-text",
|
|
||||||
"dialog:allow-open",
|
|
||||||
"dialog:allow-save",
|
|
||||||
"fs:allow-read-dir",
|
|
||||||
"fs:allow-read-file",
|
|
||||||
"fs:allow-read-text-file",
|
|
||||||
{
|
|
||||||
"identifier": "fs:scope",
|
|
||||||
"allow": [
|
|
||||||
{
|
|
||||||
"path": "$APPDATA"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "$APPDATA/**"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"clipboard-manager:allow-read-text",
|
|
||||||
"clipboard-manager:allow-write-text",
|
|
||||||
"core:webview:allow-set-webview-zoom",
|
|
||||||
"core:window:allow-close",
|
|
||||||
"core:window:allow-internal-toggle-maximize",
|
|
||||||
"core:window:allow-is-fullscreen",
|
|
||||||
"core:window:allow-is-maximized",
|
|
||||||
"core:window:allow-maximize",
|
|
||||||
"core:window:allow-minimize",
|
|
||||||
"core:window:allow-set-decorations",
|
|
||||||
"core:window:allow-set-title",
|
|
||||||
"core:window:allow-show",
|
|
||||||
"core:window:allow-start-dragging",
|
|
||||||
"core:window:allow-theme",
|
|
||||||
"core:window:allow-unmaximize",
|
|
||||||
"opener:allow-default-urls",
|
|
||||||
"opener:allow-open-path",
|
|
||||||
"opener:allow-open-url",
|
|
||||||
"opener:allow-reveal-item-in-dir",
|
|
||||||
"shell:allow-open",
|
|
||||||
"yaak-fonts:default",
|
|
||||||
"yaak-mac-window:default"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
Before Width: | Height: | Size: 6.1 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 6.7 KiB |
|
Before Width: | Height: | Size: 7.0 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 7.6 KiB |
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 4.4 KiB |
|
Before Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 4.4 KiB |
|
Before Width: | Height: | Size: 6.7 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 6.7 KiB |
|
Before Width: | Height: | Size: 8.9 KiB |
|
Before Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 8.9 KiB |
|
Before Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 848 B |
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 8.3 KiB |
|
Before Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 7.1 KiB |
|
Before Width: | Height: | Size: 7.8 KiB |
|
Before Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 356 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 17 KiB |