-
Notifications
You must be signed in to change notification settings - Fork 0
feat: add bahar CLI for direct dictionary/flashcard data access #43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,103 @@ | ||
| --- | ||
| name: bahar-data-access | ||
| description: > | ||
| Explains how an agent can access a Bahar user's own dictionary and flashcard data: | ||
| it lives in a personal Turso SQLite database (not behind a REST API), the `bahar` | ||
| CLI handles login and hands back direct connection credentials, and the agent then | ||
| queries that database directly with any SQL/libsql client. Use when a user asks to | ||
| look up, search, review, or analyze their own dictionary entries, flashcards, decks, | ||
| or study stats via chat — e.g. "what words am I struggling with", "add this word to | ||
| my dictionary", "quiz me on my hardest cards", "how many words have I added this | ||
| month". | ||
| --- | ||
|
|
||
| # Bahar data access (for agents) | ||
|
|
||
| ## Where the data lives | ||
|
|
||
| Each Bahar user has their own personal SQLite database, hosted on Turso, separate from | ||
| the app's central database (auth, billing, etc.). There is no REST API for dictionary or | ||
| flashcard data — the web and mobile apps connect to this per-user database directly, and | ||
| so should you. | ||
|
|
||
| ## Step 1 — log in (once per machine) | ||
|
|
||
| ```bash | ||
| bahar login | ||
| ``` | ||
|
|
||
| Opens the user's browser to sign in to their Bahar account, then stores a personal API | ||
| key locally (`~/.config/bahar/credentials.json`, or the platform equivalent). Only needs | ||
| to be run again if the user explicitly logs out or the key is revoked. | ||
|
|
||
| ## Step 2 — get connection info | ||
|
|
||
| ```bash | ||
| bahar db-info | ||
| ``` | ||
|
|
||
| Prints JSON with everything needed to connect: `hostname`, `db_name`, and a short-lived | ||
| `access_token` (refreshed automatically by the CLI's backend when it's close to | ||
| expiring, so always call this fresh rather than caching the token yourself). | ||
|
|
||
| ## Step 3 — connect directly | ||
|
|
||
| Use any libsql-compatible client with the `hostname` and `access_token` from step 2, | ||
| e.g. in Node/Bun: | ||
|
|
||
| ```ts | ||
| import { createClient } from "@libsql/client"; | ||
|
|
||
| const client = createClient({ | ||
| url: `libsql://${hostname}`, | ||
| authToken: access_token, | ||
| }); | ||
|
|
||
| const result = await client.execute("SELECT word, translation FROM dictionary_entries LIMIT 5"); | ||
| ``` | ||
|
|
||
| Any language with a libsql/sqlite client works the same way — this isn't Node-specific. | ||
|
|
||
| ## Step 4 — discover the schema live, don't assume it | ||
|
|
||
| Don't hardcode column names from this file into your queries. The schema evolves over | ||
| time (Bahar runs real migrations against it), so the only reliable source of truth is | ||
| the database itself: | ||
|
|
||
| ```sql | ||
| SELECT name, sql FROM sqlite_master WHERE type = 'table'; | ||
| ``` | ||
|
|
||
| Run this once at the start of a session to see the exact current columns before writing | ||
| queries, rather than guessing. | ||
|
|
||
| ## Orientation — tables you'll typically care about | ||
|
|
||
| These names are stable; treat their *columns* as unknown until you've introspected them | ||
| per Step 4. | ||
|
|
||
| - `dictionary_entries` — the user's personal Arabic dictionary (word, translation, | ||
| definition, morphology, tags, examples, etc.) | ||
| - `flashcards` — one row per study direction (forward/reverse) per dictionary entry, | ||
| holding FSRS (spaced-repetition) scheduling state | ||
| - `decks` — user-defined groupings of flashcards | ||
| - `user_stats` — aggregate study stats | ||
| - `settings` — per-user app settings | ||
| - `migrations` — internal schema-version bookkeeping; not user data, ignore it | ||
|
|
||
| ## Gotchas | ||
|
|
||
| - Several `dictionary_entries` columns (`root`, `tags`, `antonyms`, `examples`, | ||
| `morphology`) are stored as JSON *text*. The web/mobile apps parse them through | ||
| Drizzle's `mode: "json"` on the way out — a raw SQL client will hand you back the raw | ||
| JSON string, so `JSON.parse()` (or your language's equivalent) it yourself. | ||
| - `flashcards` scheduling fields (`difficulty`, `stability`, `due`, `state`, `reps`, | ||
| `lapses`, etc.) are FSRS algorithm state, not plain data. Reading them for | ||
| study-coaching purposes is safe; writing to them to record a review requires running | ||
| the actual FSRS update logic first (see `packages/fsrs` in this repo) — don't | ||
| hand-write a new `due`/`state` value directly, it will desync the schedule. | ||
| Straightforward additive writes (new dictionary entries, new flashcards/decks) don't | ||
| have this concern. | ||
| - The `access_token` from `bahar db-info` is a real credential scoped to that user's | ||
| database. Treat it like a password — don't print it to logs or persist it anywhere | ||
| beyond what's needed to make the connection. |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,88 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name: Release CLI | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| on: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| workflow_dispatch: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| push: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| tags: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - "cli-v*" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| jobs: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| build: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name: Build binaries | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| runs-on: ubuntu-latest | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| steps: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - uses: actions/checkout@v4 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win Set
🔒 Proposed fix - uses: actions/checkout@v4
+ with:
+ persist-credentials: falseFlagged by zizmor: 📝 Committable suggestion
Suggested change
🧰 Tools🪛 zizmor (1.26.1)[warning] 13-13: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false (artipacked) Source: Linters/SAST tools |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - uses: oven-sh/setup-bun@v2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bun-version: "1.3.5" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - uses: pnpm/action-setup@v4 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| version: 8.15.3 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Install dependencies | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: pnpm install --frozen-lockfile | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Verify release URLs are configured | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if [ -z "${{ vars.BAHAR_WEB_URL }}" ] || [ -z "${{ vars.BAHAR_API_URL }}" ]; then | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| echo "::error::Set the BAHAR_WEB_URL and BAHAR_API_URL repository variables (Settings > Secrets and variables > Actions > Variables) before cutting a CLI release." | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| exit 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Build binaries | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| working-directory: apps/cli | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| declare -A targets=( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| [bun-linux-x64]=bahar-linux-x64 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| [bun-darwin-x64]=bahar-darwin-x64 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| [bun-darwin-arm64]=bahar-darwin-arm64 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| [bun-windows-x64]=bahar-windows-x64.exe | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for target in "${!targets[@]}"; do | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| asset="${targets[$target]}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bun build --compile \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --target="$target" \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --minify-whitespace \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --minify-syntax \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --define "process.env.BAHAR_WEB_URL='${{ vars.BAHAR_WEB_URL }}'" \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --define "process.env.BAHAR_API_URL='${{ vars.BAHAR_API_URL }}'" \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --outfile "$asset" \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| src/index.ts | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| done | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+26
to
+54
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win Avoid direct template interpolation of
🔒 Proposed fix - name: Verify release URLs are configured
+ env:
+ BAHAR_WEB_URL: ${{ vars.BAHAR_WEB_URL }}
+ BAHAR_API_URL: ${{ vars.BAHAR_API_URL }}
run: |
- if [ -z "${{ vars.BAHAR_WEB_URL }}" ] || [ -z "${{ vars.BAHAR_API_URL }}" ]; then
+ if [ -z "$BAHAR_WEB_URL" ] || [ -z "$BAHAR_API_URL" ]; then
echo "::error::Set the BAHAR_WEB_URL and BAHAR_API_URL repository variables (Settings > Secrets and variables > Actions > Variables) before cutting a CLI release."
exit 1
fi
- name: Build binaries
working-directory: apps/cli
+ env:
+ BAHAR_WEB_URL: ${{ vars.BAHAR_WEB_URL }}
+ BAHAR_API_URL: ${{ vars.BAHAR_API_URL }}
run: |
...
bun build --compile \
--target="$target" \
--minify-whitespace \
--minify-syntax \
- --define "process.env.BAHAR_WEB_URL='${{ vars.BAHAR_WEB_URL }}'" \
- --define "process.env.BAHAR_API_URL='${{ vars.BAHAR_API_URL }}'" \
+ --define "process.env.BAHAR_WEB_URL='$BAHAR_WEB_URL'" \
+ --define "process.env.BAHAR_API_URL='$BAHAR_API_URL'" \
--outfile "$asset" \
src/index.ts
doneFlagged by zizmor: 📝 Committable suggestion
Suggested change
🧰 Tools🪛 zizmor (1.26.1)[info] 28-28: code injection via template expansion (template-injection): may expand into attacker-controllable code (template-injection) [info] 28-28: code injection via template expansion (template-injection): may expand into attacker-controllable code (template-injection) [info] 50-50: code injection via template expansion (template-injection): may expand into attacker-controllable code (template-injection) [info] 51-51: code injection via template expansion (template-injection): may expand into attacker-controllable code (template-injection) 🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - uses: actions/upload-artifact@v4 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name: binaries | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| path: | | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| apps/cli/bahar-linux-x64 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| apps/cli/bahar-darwin-x64 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| apps/cli/bahar-darwin-arm64 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| apps/cli/bahar-windows-x64.exe | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| release: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name: Create GitHub release | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| needs: build | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| runs-on: ubuntu-latest | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| permissions: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| contents: write | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| steps: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - uses: actions/download-artifact@v4 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name: binaries | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| path: dist | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Create release and upload binaries | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| gh release create "${{ github.ref_name }}" \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| dist/bahar-linux-x64 \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| dist/bahar-darwin-x64 \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| dist/bahar-darwin-arm64 \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| dist/bahar-windows-x64.exe \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --repo "${{ github.repository }}" \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --title "Bahar CLI ${{ github.ref_name }}" \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --generate-notes | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+77
to
+88
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win Template-inject Git ref names permit characters like 🔒 Proposed fix - name: Create release and upload binaries
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ REF_NAME: ${{ github.ref_name }}
+ REPOSITORY: ${{ github.repository }}
run: |
- gh release create "${{ github.ref_name }}" \
+ gh release create "$REF_NAME" \
dist/bahar-linux-x64 \
dist/bahar-darwin-x64 \
dist/bahar-darwin-arm64 \
dist/bahar-windows-x64.exe \
- --repo "${{ github.repository }}" \
- --title "Bahar CLI ${{ github.ref_name }}" \
+ --repo "$REPOSITORY" \
+ --title "Bahar CLI $REF_NAME" \
--generate-notesFlagged by zizmor as 📝 Committable suggestion
Suggested change
🧰 Tools🪛 zizmor (1.26.1)[error] 81-81: code injection via template expansion (template-injection): may expand into attacker-controllable code (template-injection) [error] 87-87: code injection via template expansion (template-injection): may expand into attacker-controllable code (template-injection) 🤖 Prompt for AI AgentsSource: Linters/SAST tools |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| CREATE TABLE `apikeys` ( | ||
| `id` text PRIMARY KEY NOT NULL, | ||
| `name` text, | ||
| `start` text, | ||
| `prefix` text, | ||
| `key` text NOT NULL, | ||
| `user_id` text NOT NULL, | ||
| `refill_interval` integer, | ||
| `refill_amount` integer, | ||
| `last_refill_at` integer, | ||
| `enabled` integer DEFAULT true, | ||
| `rate_limit_enabled` integer DEFAULT true, | ||
| `rate_limit_time_window` integer DEFAULT 86400000, | ||
| `rate_limit_max` integer DEFAULT 10, | ||
| `request_count` integer DEFAULT 0, | ||
| `remaining` integer, | ||
| `last_request` integer, | ||
| `expires_at` integer, | ||
| `created_at` integer NOT NULL, | ||
| `updated_at` integer NOT NULL, | ||
| `permissions` text, | ||
| `metadata` text, | ||
| FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE cascade | ||
| ); | ||
| --> statement-breakpoint | ||
| CREATE INDEX `apikeys_key_idx` ON `apikeys` (`key`);--> statement-breakpoint | ||
| CREATE INDEX `apikeys_userId_idx` ON `apikeys` (`user_id`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
Add an explicit top-level
permissionsblock.No workflow-level
permissionsis set, so thebuildjob inherits the repo/org default token permissions (which may be broad read/write). Sincebuildonly checks out and compiles code (and runspnpm install, which executes third-party install scripts), it should be scoped to the minimum required.🔒 Proposed fix
name: Release CLI on: workflow_dispatch: push: tags: - "cli-v*" + +permissions: + contents: readFlagged by zizmor:
overly broad permissions (excessive-permissions): default permissions used due to no permissions: block.📝 Committable suggestion
🧰 Tools
🪛 zizmor (1.26.1)
[warning] 1-89: overly broad permissions (excessive-permissions): default permissions used due to no permissions: block
(excessive-permissions)
🤖 Prompt for AI Agents
Source: Linters/SAST tools