Skip to content

Commit bef13dc

Browse files
authored
Merge pull request #70 from jcode-works/develop
release: promote commercial desktop app and multilingual TTS
2 parents e5f0c23 + 5d50892 commit bef13dc

101 files changed

Lines changed: 12487 additions & 1237 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/dependabot-auto-merge.yml

Lines changed: 0 additions & 36 deletions
This file was deleted.

.github/workflows/npm-publish.yml

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,7 @@ on:
55
branches: [main]
66
workflow_dispatch:
77

8-
permissions:
9-
actions: write
10-
contents: write
11-
issues: write
12-
id-token: write
13-
pull-requests: write
8+
permissions: {}
149

1510
concurrency:
1611
group: release-npm-${{ github.ref }}
@@ -20,6 +15,11 @@ jobs:
2015
release:
2116
name: Semantic release
2217
runs-on: ubuntu-latest
18+
permissions:
19+
contents: write
20+
issues: write
21+
id-token: write
22+
pull-requests: write
2323
environment:
2424
name: npm-publish
2525
url: https://www.npmjs.com/package/@jcode.labs/ragmir
@@ -74,6 +74,9 @@ jobs:
7474
runs-on: ubuntu-latest
7575
needs: release
7676
if: needs.release.outputs.version != ''
77+
permissions:
78+
actions: write
79+
contents: read
7780
steps:
7881
- name: Trigger landing deploy with version
7982
uses: actions/github-script@v7

AGENTS.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,16 @@
101101
- `packages/ragmir-app` is the cross-platform Tauri desktop/mobile shell. Root `pnpm build` validates
102102
the frontend bundle only; native `tauri build`, `tauri ios *`, and `tauri android *` commands stay
103103
explicit and are not part of npm release validation.
104+
- Desktop app config editing should use structured shadcn-style controls from
105+
`@jcode.labs/ragmir-ui`. JSON remains the `.ragmir/config.json` file format, not the primary app
106+
editing experience.
107+
- For Tauri app file and folder pickers triggered from the UI, prefer the official
108+
`@tauri-apps/plugin-dialog` JavaScript `open(...)` API from the click handler. Do not add Rust
109+
commands that call `blocking_*` dialog APIs for frontend-triggered picker flows; they can deadlock
110+
the Tauri event loop and leave app loading state stuck. If a dedicated Rust picker command becomes
111+
necessary, use the non-blocking `pick_*` callback APIs and validate the real `pnpm dev:app` flow by
112+
clicking the control, opening the native picker, cancelling it, and confirming the loading state
113+
clears.
104114
- Distribute the Ragmir app through direct downloads and sideloadable installers, not App Store or
105115
Play Store flows. Desktop installers and Android APK-style distribution are first-class; iOS stays
106116
deferred until a compliant non-store channel is chosen.
@@ -153,6 +163,28 @@
153163
Transformers.js text generation for `rgr chat`; `rgr chat setup` is the explicit one-command
154164
preload path for `.ragmir/models/chat`, and normal answers must keep remote model loading disabled
155165
unless the user opts into `--allow-remote-models`.
166+
- In `packages/ragmir-app`, keep model preloads explicit in the Tauri sidecar: setup/prepare flows
167+
may pass `--allow-remote-models` only for one-time embedding/chat/TTS preload commands, while
168+
normal chat answers and audio rendering must use offline/local modes after preload.
169+
- In `packages/ragmir-app`, chat UX must stay non-blocking: append the user message and a pending
170+
assistant bubble before invoking native chat, show visible thinking/streaming/error states, render
171+
assistant Markdown, keep recent thread context local and explicit, and run long native CLI work
172+
through async Tauri commands or `spawn_blocking` so the webview does not freeze.
173+
- In `packages/ragmir-app`, distinguish Ragmir Chat from external coding agents. Local chat is the
174+
only fully private in-app conversation path. Codex, Claude, Kimi, OpenCode, Cline, or generic MCP
175+
modes should be presented as a handoff that generates/copies helper config and prompts for the
176+
external agent; do not build a fake duplicate chat UI for agents that already have their own chat.
177+
Always warn that prompts, retrieved snippets, and pasted confidential content may leave the
178+
machine through cloud agents even though the Ragmir index and MCP server stay local.
179+
- In `packages/ragmir-app`, chat TTS belongs on assistant messages, not as a vague global export:
180+
render the selected answer with `rgr audio --offline`, show per-message rendering/playing/error
181+
states, read generated files through Tauri's scoped asset protocol, and keep TTS preload as an
182+
explicit non-sensitive setup action.
183+
- In `packages/ragmir-app`, prepare direct-folder workspaces in bootstrap order: first write or
184+
repair `.ragmir/config.json` with `sources: ["."]` and the safe `local-hash` provider, then run
185+
`rgr models pull --enable`, then rebuild with Transformers. Do not set
186+
`embeddingProvider: "transformers"` before the model preload exists, or `doctor --fix` can ingest
187+
against a missing local model.
156188
- Keep report generation separate from core retrieval. The `ragmir-markdown-report` skill writes cited
157189
Markdown reports under ignored `.ragmir/reports/` by default and must distinguish evidence,
158190
inference, uncertainty, missing documents, and professional-review items.
@@ -237,6 +269,11 @@ any other), because several agents may run against this repo in parallel.
237269
protected-branch back-merge), name it clearly and delete it once merged.
238270
- **Respect other agents' work.** Before editing, run `git status` and check for other running agents
239271
or processes; never stage, commit, or discard uncommitted changes you did not make.
272+
- **Capture durable agent lessons in the repo.** When a bug, review, or user correction reveals a
273+
repeatable AI-agent trap, update the nearest shared agent instructions in the same task:
274+
`AGENTS.md` for cross-agent project rules, and `CLAUDE.md` only for Claude Code-specific behavior.
275+
Keep the entry concise, factual, and tied to a reproducible workflow; do not rely on tool-local
276+
memory as the only place for team-shared rules.
240277

241278
## Coding Conventions
242279

CLAUDE.md

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ Guardrails" in `AGENTS.md`.
2121
pnpm bootstrap # mise install (pinned Node/Rust) && pnpm install
2222
pnpm build # builds UI, app frontend, landing, TTS, chat, then Ragmir Core
2323
pnpm check # typecheck UI/app/landing/TTS/chat/core
24-
pnpm dev:app # run the Vite frontend for the Tauri shell
24+
pnpm dev:app # run the Tauri desktop shell; requires Rust on PATH via mise
2525
pnpm dev:landing # run the Astro landing locally
2626
pnpm example # build core + run the library-API smoke against the local build (examples/library-api-demo)
2727
pnpm lint # Biome CI (format + lint check, no writes)
@@ -41,6 +41,14 @@ Run only the chat package tests: `pnpm --filter @jcode.labs/ragmir-chat test`
4141

4242
Tests are colocated as `packages/*/src/*.test.ts` and run on the TypeScript sources.
4343

44+
## Claude memory and shared rules
45+
46+
Claude Code has auto memory and `/memory`, but those notes are local to the machine and are not a
47+
replacement for committed project rules. When a user correction, review, or regression reveals a
48+
repeatable trap, add a concise shared rule to `AGENTS.md`; only add Claude-specific behavior here.
49+
Use `.claude/rules/` later only if the rule needs path-specific loading instead of every-session
50+
context.
51+
4452
## `dist/` is gitignored build output — critical
4553

4654
All `packages/*/dist/` directories (`ragmir-core`, `ragmir-tts`, `ragmir-chat`, `ragmir-app`,
@@ -116,6 +124,18 @@ foundation, but with Ragmir tokens and no WorkoutGen product copy, analytics, CD
116124
Tauri v2 shell using the same UI package; root build validates its Vite frontend, while native Tauri
117125
desktop/mobile builds are explicit `pnpm --filter @jcode.labs/ragmir-app tauri:*` commands.
118126

127+
Tauri dialog trap: for UI-triggered file/folder selection, use
128+
`@tauri-apps/plugin-dialog` `open(...)` from the frontend click handler. Do not add Rust commands
129+
that call `blocking_*` dialog APIs for these flows; they can deadlock the native event loop and leave
130+
React loading state stuck. Validate by running `mise exec rust -- pnpm dev:app`, clicking the picker
131+
button, cancelling the native dialog, and confirming the UI leaves its loading state.
132+
133+
Tauri model-preload trap: when editing `packages/ragmir-app/src-tauri/src/lib.rs`, keep setup
134+
commands explicit about the network boundary. One-time model preloads may pass
135+
`--allow-remote-models`; normal chat/audio commands must stay offline after preload.
136+
For app `Prepare` flows, keep the bootstrap order from `AGENTS.md`: write direct-folder sources with
137+
`local-hash` first, preload semantic models second, then rebuild with Transformers.
138+
119139
Key behaviors to keep in mind before editing:
120140

121141
- **Config resolution is caller-relative.** `loadConfig` walks up from `cwd` looking for

README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -690,9 +690,11 @@ npx rgr-tts render /tmp/RAGMIR-SUMMARY-project.txt \
690690
```
691691

692692
The default standalone engine is `transformers` and the default language is `fr`. Pass
693-
`--lang en|es|fr` (or `RAGMIR_TTS_LANG`) to switch language: it selects the matching self-contained
694-
offline model (`Xenova/mms-tts-eng`, `Xenova/mms-tts-spa`, or `Xenova/mms-tts-fra`) and, on the Edge
695-
path, a native neural voice. Override the model directly with `--model` or `RAGMIR_TTS_MODEL`.
693+
`--lang en|es|fr|ja|th|zh` (or `RAGMIR_TTS_LANG`) to switch language. English, Spanish, and French
694+
select matching self-contained offline models (`Xenova/mms-tts-eng`, `Xenova/mms-tts-spa`, or
695+
`Xenova/mms-tts-fra`) and native Edge voices. Japanese, Thai, and Mandarin Chinese currently select
696+
native Edge voices; for offline rendering in those languages, pass a Transformers.js-compatible
697+
model directly with `--model` or `RAGMIR_TTS_MODEL`.
696698

697699
See [`docs/offline-tts-preload.md`](./docs/offline-tts-preload.md) for the exact preload and
698700
offline-check workflow.

docs/api-reference.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ Useful result fields:
7777
| `ingested` | `IngestResult` when auto-ingest ran; otherwise `null`. |
7878
| `doctor` | Final readiness report. |
7979
| `nextSteps` | User-facing next actions. |
80+
| `configurationPrompt` | English copy-paste prompt for an AI assistant or local chat to tune repository-specific `sources` entries safely. |
8081

8182
### `loadConfig(start?)`
8283

docs/cli-reference.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Ragmir ships three CLIs:
1010

1111
| Command | Use it when |
1212
| --- | --- |
13-
| `rgr setup` | Initialize Ragmir, install the agent kit, run doctor, and ingest when safe. |
13+
| `rgr setup` | Initialize Ragmir, install the agent kit, run doctor, ingest when safe, and print a copyable AI prompt for source tuning. |
1414
| `rgr setup --semantic` | Run first setup and explicitly download the configured Transformers.js embedding model for higher-quality semantic retrieval. |
1515
| `rgr init` | Create `.ragmir/config.json` (with a `sources` array), `.ragmir/raw/`, and Git ignore rules. |
1616
| `rgr doctor` | Diagnose setup, index freshness, security warnings, and the next command to run. |
@@ -77,20 +77,24 @@ Ragmir ships three CLIs:
7777
| `--top-k <number>` | `search`, `ask`, `chat`, `research`, `evaluate` | Number of passages to return or keep. |
7878
| `--fail-under <recall>` | `evaluate` | Exit non-zero only when recall is below a threshold from `0` to `1`; without this option evaluation remains strict and fails on any miss. |
7979
| `--days <number>` | `usage-report` | Number of recent days to include in the metadata-only usage summary. |
80-
| `--json` | `doctor`, `ingest`, `search`, `ask`, `chat`, `research`, `route-prompt`, `evaluate`, `audit`, `usage-report`, `status`, `security-audit`, `audio --doctor`, `rgr-chat doctor`, `rgr-tts doctor` | Print machine-readable JSON. |
80+
| `--json` | `setup`, `doctor`, `ingest`, `search`, `ask`, `chat`, `research`, `route-prompt`, `evaluate`, `audit`, `usage-report`, `status`, `security-audit`, `audio --doctor`, `rgr-chat doctor`, `rgr-tts doctor` | Print machine-readable JSON. |
8181
| `--compact` | `search`, `research` | Return short snippets instead of full retrieved passages. |
8282
| `--no-code` | `research` | Skip the lightweight repository code scan. |
8383
| `--unsupported` | `audit` | List skipped file paths and reasons. |
8484
| `--strict` | `security-audit` | Exit non-zero when warnings exist. |
8585
| `--offline` | `chat`, `audio`, `rgr-chat answer`, `rgr-tts render` | Disable remote model downloads and force the local Transformers.js path. |
8686
| `--allow-remote-models` | `chat`, `audio`, `rgr-chat answer`, `rgr-tts render` | Explicitly allow model downloads for Transformers.js. |
8787
| `--engine edge` | `audio`, `rgr-tts render` | Use online Edge TTS for MP3 output. |
88-
| `--lang <en\|es\|fr>` | `audio`, `rgr-tts render` | Select the TTS language; picks the offline model and Edge voice. Default `fr`. |
88+
| `--lang <en\|es\|fr\|ja\|th\|zh>` | `audio`, `rgr-tts render` | Select the TTS language. `en`, `es`, and `fr` have default offline models; `ja`, `th`, and `zh` use Edge voices unless `--model` supplies a compatible offline model. Default `fr`. |
8989

9090
See [`offline-chat-preload.md`](./offline-chat-preload.md) and
9191
[`offline-tts-preload.md`](./offline-tts-preload.md) before using `--offline` on a fully air-gapped
9292
machine.
9393

94+
`rgr setup` ends with an English prompt between copy markers. Paste it into an AI assistant or local
95+
chat to ask for repository-specific `sources` recommendations while excluding secrets, generated
96+
files, dependency folders, caches, and unnecessary locale noise.
97+
9498
## External Text Extraction Configuration
9599

96100
OCR and legacy binary extraction are intentionally configuration-based rather than default CLI flags.

docs/offline-tts-preload.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ Use this workflow when you want confidential audio summaries to render without n
1212
- Render confidential narration only after the offline check succeeds.
1313
- Keep `.ragmir/models/tts/` and `.ragmir/audio/` untracked.
1414
- Do not use `--engine edge` for confidential content unless online TTS is explicitly acceptable.
15+
- Default offline models are configured for `en`, `es`, and `fr`. For `ja`, `th`, or `zh`, pass a
16+
Transformers.js-compatible TTS model explicitly with `--model` before relying on offline rendering.
1517

1618
The preload step downloads public model files. It should not need to send narration text to a remote
1719
TTS service, but using synthetic text keeps the operation easy to audit.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
"build": "pnpm --filter @jcode.labs/ragmir-ui build && pnpm --filter @jcode.labs/ragmir-app build && pnpm --filter @jcode.labs/ragmir-landing build && pnpm --filter @jcode.labs/ragmir-license-webhook build && pnpm --filter @jcode.labs/ragmir-tts build && pnpm --filter @jcode.labs/ragmir-chat build && pnpm --filter @jcode.labs/ragmir build",
4040
"check": "pnpm --filter @jcode.labs/ragmir-ui check && pnpm --filter @jcode.labs/ragmir-app check && pnpm --filter @jcode.labs/ragmir-landing check && pnpm --filter @jcode.labs/ragmir-license-webhook check && pnpm --filter @jcode.labs/ragmir-tts check && pnpm --filter @jcode.labs/ragmir-chat check && pnpm --filter @jcode.labs/ragmir check",
4141
"commitlint": "commitlint --from=HEAD~1 --to=HEAD --verbose",
42-
"dev:app": "pnpm --filter @jcode.labs/ragmir-app dev",
42+
"dev:app": "pnpm --filter @jcode.labs/ragmir-app tauri:dev",
4343
"dev:landing": "pnpm --filter @jcode.labs/ragmir-landing dev",
4444
"example": "pnpm --filter @jcode.labs/ragmir build && node packages/ragmir-core/examples/library-api-demo/run.mjs",
4545
"format": "biome format --write .",

packages/ragmir-app/package.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
"scripts": {
99
"build": "tsc -p tsconfig.json --noEmit && vite build",
1010
"check": "tsc -p tsconfig.json --noEmit",
11-
"dev": "vite",
11+
"dev": "tauri dev",
12+
"dev:web": "vite",
1213
"license:from-lemonsqueezy": "node scripts/license-from-lemonsqueezy.mjs",
1314
"license:lemonsqueezy:smoke": "node scripts/license-from-lemonsqueezy-smoke.mjs",
1415
"license:issue": "node scripts/license-issue.mjs",
@@ -39,9 +40,11 @@
3940
"dependencies": {
4041
"@jcode.labs/ragmir-ui": "workspace:*",
4142
"@tauri-apps/api": "^2.10.0",
43+
"@tauri-apps/plugin-dialog": "^2.7.1",
4244
"lucide-react": "^1.21.0",
4345
"react": "19.2.7",
44-
"react-dom": "19.2.7"
46+
"react-dom": "19.2.7",
47+
"react-markdown": "^10.1.0"
4548
},
4649
"devDependencies": {
4750
"@tauri-apps/cli": "^2.10.0",

0 commit comments

Comments
 (0)