@7n/tauri-components 0.7.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/package.json +5 -1
  2. package/src/components/docs/AgentDialog.md +35 -0
  3. package/src/components/docs/AuditDialog.md +28 -0
  4. package/src/components/docs/BaseDialog.md +22 -0
  5. package/src/components/docs/DialogActions.md +24 -0
  6. package/src/components/docs/RequestView.md +25 -0
  7. package/src/components/docs/StatePill.md +20 -0
  8. package/src/components/docs/index.md +28 -0
  9. package/src/components/docs/status.md +29 -0
  10. package/src/core/acp-agent.js +192 -0
  11. package/src/core/acp-kit.js +260 -0
  12. package/src/core/docs/acp-agent.md +43 -0
  13. package/src/core/docs/acp-kit.md +50 -0
  14. package/src/core/docs/agent-handler.md +31 -0
  15. package/src/core/docs/agent-kit.md +25 -0
  16. package/src/core/docs/dispatch.md +30 -0
  17. package/src/core/docs/llm.md +29 -0
  18. package/src/core/docs/manifest.md +30 -0
  19. package/src/core/docs/omlx-models.md +30 -0
  20. package/src/core/docs/resolve-omlx-base-url.md +40 -0
  21. package/src/core/docs/scope.md +32 -0
  22. package/src/core/docs/tools.md +28 -0
  23. package/src/docs/index.md +54 -0
  24. package/src/index.js +12 -0
  25. package/src/testing/docs/index.md +24 -0
  26. package/src/testing/docs/quasar.md +28 -0
  27. package/src/vue/docs/index.md +28 -0
  28. package/src/vue/docs/journal-store-tauri.md +27 -0
  29. package/src/vue/docs/transports.md +25 -0
  30. package/src/vue/docs/use-acp-agent.md +29 -0
  31. package/src/vue/docs/use-agent.md +29 -0
  32. package/src/vue/docs/use-omlx.md +30 -0
  33. package/src/vue/docs/use-updater.md +31 -0
  34. package/src/vue/index.js +2 -0
  35. package/src/vue/use-acp-agent.js +109 -0
  36. package/src/vue/use-updater.js +116 -0
@@ -0,0 +1,54 @@
1
+ ---
2
+ docgen:
3
+ source: npm/src/index.js
4
+ crc: 4c3b4830
5
+ model: omlx/gemma-4-e4b-it-OptiQ-4bit
6
+ score: 100
7
+ issues: judge:inaccurate:0.99
8
+ judgeModel: openai-codex/gpt-5.4-mini
9
+ ---
10
+
11
+ # index.js
12
+
13
+ ## Огляд
14
+
15
+ Модуль керує життєвим циклом агента, охоплюючи етапи ініціалізації, виконання та завершення роботи. Він відповідає за налаштування конфігурації, реєстрацію обробників запитів та інструментів. Модуль ініціалізує сесії та забезпечує взаємодію агента з зовнішніми системами, такими як MCP та Omlx, використовуючи лише дані, які є read-only.
16
+
17
+ ## Поведінка
18
+
19
+ 1. Налаштовує конфігурацію агента.
20
+ 2. Припиняє активну сесію агента.
21
+ 3. Створює нову сесію агента.
22
+ 4. Реєструє обробник запитів на дозвіл агента.
23
+ 5. Реєструє обробник виклику інструменту агента.
24
+ 6. Відповідає на запит агента про дозвіл.
25
+ 7. Відповідає на виклик інструменту агента.
26
+ 8. Виконує один хід агента.
27
+ 9. Ініціює міст між агентом та MCP.
28
+ 10. Створює набір інструментів агента.
29
+ 11. Створює набір інструментів агента.
30
+ 12. Обробляє схвалення агента.
31
+ 13. Обробляє загальний запит агента.
32
+ 14. Обробляє відповідь агента.
33
+ 15. Створює диспетчер.
34
+ 16. Валідує вхідні дані.
35
+ 17. Створює конфігурацію чату з OpenAI.
36
+ 18. Запускає роботу агента.
37
+ 19. Перелічує моделі Omlx.
38
+ 20. Вирішує модель Omlx.
39
+ 21. Визначає базовий URL Omlx.
40
+ 22. Перевіряє, чи є URL Omlx прямим.
41
+ 23. Вирішує базовий URL Omlx з кешуванням.
42
+ 24. Перелічує доступні інструменти.
43
+ 25. Генерує схему JSON для інструменту.
44
+ 26. Отримує маніфест інструмента.
45
+ 27. Класифікує елементи.
46
+ 28. Визначає рівні акторів за замовчуванням.
47
+ 29. Створює обмежений маніфест.
48
+ 30. Отримує імена інструментів з обмеженням.
49
+ 31. Отримує конкретний інструмент.
50
+
51
+ ## Гарантії поведінки
52
+
53
+ - Read-only: не виконує операцій запису (ФС/БД).
54
+ - Кешує результати в межах одного прогону.
package/src/index.js CHANGED
@@ -3,6 +3,18 @@
3
3
  // consumers (CLI orchestrators, MCP wrappers); the Vue/Quasar layers live under
4
4
  // the ./vue and ./components subpaths.
5
5
 
6
+ export {
7
+ acpConfig,
8
+ cancelAcpSession,
9
+ createAcpSession,
10
+ onAcpPermissionRequest,
11
+ onAcpToolCall,
12
+ respondAcpPermission,
13
+ respondAcpToolCall,
14
+ runAcpTurn,
15
+ startAcpMcpBridge,
16
+ } from './core/acp-agent.js'
17
+ export { createAcpAgentKit } from './core/acp-kit.js'
6
18
  export { createAgentKit } from './core/agent-kit.js'
7
19
  export { handleApprove, handleRequest, handleRespond } from './core/agent-handler.js'
8
20
  export { createDispatch, validateInput } from './core/dispatch.js'
@@ -0,0 +1,24 @@
1
+ ---
2
+ docgen:
3
+ source: npm/src/testing/index.js
4
+ crc: 64006a18
5
+ model: omlx/gemma-4-e4b-it-OptiQ-4bit
6
+ score: 100
7
+ issues: judge:inaccurate:0.96
8
+ judgeModel: openai-codex/gpt-5.4-mini
9
+ ---
10
+
11
+ # index.js
12
+
13
+ ## Огляд
14
+
15
+ Цей файл надає механізм для монтування компонентів Quasar. Він забезпечує можливість монтування компонентів Quasar у стандартному режимі та з додатковими конфігураціями, необхідними для проведення тестів.
16
+
17
+ ## Поведінка
18
+
19
+ 1. Дозволяє монтувати компоненти Quasar для тестування.
20
+ 2. Дозволяє монтувати компоненти Quasar з додатковими налаштуваннями для тестування.
21
+
22
+ ## Гарантії поведінки
23
+
24
+ - Read-only: не виконує операцій запису (ФС/БД).
@@ -0,0 +1,28 @@
1
+ ---
2
+ docgen:
3
+ source: npm/src/testing/quasar.js
4
+ crc: 154223d8
5
+ model: omlx/gemma-4-e4b-it-OptiQ-4bit
6
+ score: 100
7
+ judgeModel: openai-codex/gpt-5.4-mini
8
+ ---
9
+
10
+ # quasar.js
11
+
12
+ ## Огляд
13
+
14
+ Модуль надає механізми для ініціалізації компонентів Vue у застосунок. Доступні два способи: пряме монтування компонента з використанням компонентів Quasar через `mountQuasar`, або монтування компонента, який автоматично інкапсулюється у стандартну структуру макету Quasar за допомогою `mountWithQuasar`. Модуль не виконує операцій запису у файлову систему чи базу даних.
15
+
16
+ ## Поведінка
17
+
18
+ mountQuasar монтує компонент Vue з зареєстрованими компонентами Quasar, не обгортаючи його у макет.
19
+ mountWithQuasar монтує компонент Vue, обгорнувши його у структуру QLayout > QPageContainer.
20
+
21
+ ## Публічний API
22
+
23
+ mountQuasar — Монтує компонент з зареєстрованим Quasar без обгортки макета.
24
+ mountWithQuasar — Монтує компонент рівня сторінки, обгорнутий у QLayout > QPageContainer.
25
+
26
+ ## Гарантії поведінки
27
+
28
+ - Read-only: не виконує операцій запису (ФС/БД).
@@ -0,0 +1,28 @@
1
+ ---
2
+ docgen:
3
+ source: npm/src/vue/index.js
4
+ crc: ac7a549c
5
+ model: omlx/gemma-4-e4b-it-OptiQ-4bit
6
+ score: 100
7
+ issues: judge:inaccurate:0.98
8
+ judgeModel: openai-codex/gpt-5.4-mini
9
+ ---
10
+
11
+ # index.js
12
+
13
+ ## Огляд
14
+
15
+ Цей файл є центральною точкою взаємодії системи. Він забезпечує механізми для комунікації з агентом ACP, загальним агентом та протоколом OMLX. Він створює сховище журналу, використовуючи механізми Tauri, та надає об'єкт для транспортування даних.
16
+
17
+ ## Поведінка
18
+
19
+ 1. Надає хук для взаємодії з агентом ACP.
20
+ 2. Надає хук для взаємодії з агентом.
21
+ 3. Надає хук для роботи з протоколом OMLX.
22
+ 4. Надає хук для роботи з оновленнями.
23
+ 5. Створює сховище журналу, що використовує механізми Tauri.
24
+ 6. Надає об'єкт для транспортування даних.
25
+
26
+ ## Гарантії поведінки
27
+
28
+ - Read-only: не виконує операцій запису (ФС/БД).
@@ -0,0 +1,27 @@
1
+ ---
2
+ docgen:
3
+ source: npm/src/vue/journal-store-tauri.js
4
+ crc: 6356740d
5
+ model: omlx/gemma-4-e4b-it-OptiQ-4bit
6
+ score: 100
7
+ issues: judge:inaccurate:0.99
8
+ judgeModel: openai-codex/gpt-5.4-mini
9
+ ---
10
+
11
+ # journal-store-tauri.js
12
+
13
+ ## Огляд
14
+
15
+ Цей модуль керує доступом до механізму журналу. Він дозволяє створювати сховище журналу та отримувати повний список існуючих записів.
16
+
17
+ ## Поведінка
18
+
19
+ 1. Викликати `createTauriJournalStore` для ініціалізації сховища журналу, яке маршрутизує операції з файловою системою через команди `tauri-plugin-agent`.
20
+ 2. Використовувати отримане сховище для створення нового запису журналу, викликаючи команду `plugin:agent|journal_create`.
21
+ 3. Використовувати отримане сховище для завантаження запису журналу за його ідентифікатором, викликаючи команду `plugin:agent|journal_load`.
22
+ 4. Використовувати отримане сховище для оновлення запису журналу за його ідентифікатором, застосовуючи патч, викликаючи команду `plugin:agent|journal_update`.
23
+ 5. Використовувати отримане сховище для отримання списку всіх записів журналу, викликаючи команду `plugin:agent|journal_list`.
24
+
25
+ ## Гарантії поведінки
26
+
27
+ - Read-only: не виконує операцій запису (ФС/БД).
@@ -0,0 +1,25 @@
1
+ ---
2
+ docgen:
3
+ source: npm/src/vue/transports.js
4
+ crc: cbde1782
5
+ model: omlx/gemma-4-e4b-it-OptiQ-4bit
6
+ score: 100
7
+ issues: judge:inaccurate:0.98
8
+ judgeModel: openai-codex/gpt-5.4-mini
9
+ ---
10
+
11
+ # transports.js
12
+
13
+ ## Огляд
14
+
15
+ Модуль ініціює виклики зовнішніх інструментів через Tauri. Він передає визначені команди та необхідні їм аргументи, а потім повертає отриманий результат виконання.
16
+
17
+ ## Поведінка
18
+
19
+ 1. Викликає команду Tauri, використовуючи визначення інструменту.
20
+ 2. Передає вхідні дані інструменту як аргументи відповідній команді.
21
+ 3. Повертає результат виконання команди.
22
+
23
+ ## Гарантії поведінки
24
+
25
+ - Read-only: не виконує операцій запису (ФС/БД).
@@ -0,0 +1,29 @@
1
+ ---
2
+ docgen:
3
+ source: npm/src/vue/use-acp-agent.js
4
+ crc: 227f9b8b
5
+ model: omlx/gemma-4-e4b-it-OptiQ-4bit
6
+ score: 100
7
+ issues: judge:inaccurate:0.97
8
+ judgeModel: openai-codex/gpt-5.4-mini
9
+ ---
10
+
11
+ # use-acp-agent.js
12
+
13
+ ## Огляд
14
+
15
+ Модуль ініціалізує шлюз агента та налаштовує доменне мостове з'єднання MCP, якщо каталог доступний. Він звертається до мережі для відправки запитів до агента. Публічна функція `useAcpAgent` використовується для передачі намірів агенту, що дозволяє оновлювати рівень моделі. Після цього модуль надає відповідь та схвалює запит. Цей модуль є Read-only і не виконує записів у файлову систему чи бази даних.
16
+
17
+ ## Поведінка
18
+
19
+ 1. Викликати `useAcpAgent` для ініціалізації шлюзу агента в додатку.
20
+ 2. Викликати `loadEnv` для зчитування за замовчуванням агента на машині та запуску доменного мостового з'єднання MCP, якщо каталог доступний.
21
+ 3. Викликати `request` для надсилання запиту з наміром.
22
+ 4. При виклику `request`, якщо в опціях вказано `modelTier`, оновити поточний рівень моделі.
23
+ 5. Викликати `request` для надсилання запиту з наміром, використовуючи поточний рівень моделі за замовчуванням, якщо він не був перевизначений.
24
+ 6. Викликати `respond` для надання відповіді на запит, використовуючи ідентифікатор запиту та повідомлення.
25
+ 7. Викликати `approve` для схвалення запиту, використовуючи ідентифікатор запиту та стан схвалення.
26
+
27
+ ## Гарантії поведінки
28
+
29
+ - Read-only: не виконує операцій запису (ФС/БД).
@@ -0,0 +1,29 @@
1
+ ---
2
+ docgen:
3
+ source: npm/src/vue/use-agent.js
4
+ crc: 84427f61
5
+ model: omlx/gemma-4-e4b-it-OptiQ-4bit
6
+ score: 100
7
+ judgeModel: openai-codex/gpt-5.4-mini
8
+ ---
9
+
10
+ # use-agent.js
11
+
12
+ ## Огляд
13
+
14
+ Модуль ініціалізує шлюз агента, надаючи йому інструменти, системний промпт та конфігурацію. Він дозволяє ініціювати запити до агента через `useAgent`, отримувати відповіді, затверджувати дії та переглядати доступні моделі. Звернення до мережі здійснюється через цей модуль.
15
+
16
+ ## Поведінка
17
+
18
+ 1. Викликати `useAgent` для ініціалізації шлюзу агента.
19
+ 2. Надати `useAgent` каталог інструментів, системний промпт, опціональне заземлення, рівні акторів, ідентичність актора, конфігурацію omlx та транспорт для інструментів.
20
+ 3. Отримати з `useAgent` посилання на базовий URL, модель, ключ API та функції для роботи з omlx.
21
+ 4. Отримати з `useAgent` посилання на журнал.
22
+ 5. Викликати `request` з отриманого шлюзу, передаючи намір та ідентичність актора, щоб ініціювати запит агента.
23
+ 6. Викликати `respond` з отриманого шлюзу, передаючи ідентифікатор запиту та повідомлення, щоб надати відповідь агенту.
24
+ 7. Викликати `approve` з отриманого шлюзу, передаючи ідентифікатор запиту та результат схвалення, щоб затвердити дію агента.
25
+ 8. Викликати `listModels` з отриманого шлюзу, щоб отримати список доступних моделей omlx.
26
+
27
+ ## Гарантії поведінки
28
+
29
+ - (специфічних машинно-виведених гарантій немає)
@@ -0,0 +1,30 @@
1
+ ---
2
+ docgen:
3
+ source: npm/src/vue/use-omlx.js
4
+ crc: d1e34b0a
5
+ model: omlx/gemma-4-e4b-it-OptiQ-4bit
6
+ score: 100
7
+ issues: judge:inaccurate:0.98
8
+ judgeModel: openai-codex/gpt-5.4-mini
9
+ ---
10
+
11
+ # use-omlx.js
12
+
13
+ ## Огляд
14
+
15
+ Модуль відповідає за ініціалізацію та кешування конфігурації для взаємодії з OMLX. Він завантажує налаштування з `settings.json` та середовища виконання, використовуючи http://127.0.0.1:8000/v1 як резервний URL. Публічна функція useOmlx звертається до мережі, виконує кешування у межах прогону. При виникненні помилок вона перехоплює їх (fail-safe), не кидаючи винятків назовні, а повертаючи порожнє значення замість винятку.
16
+
17
+ ## Поведінка
18
+
19
+ 1. Ініціалізує конфігурацію OMLX, використовуючи значення з локального сховища. Якщо значення відсутнє, використовує наданий за замовчуванням URL, який може бути `http://127.0.0.1:8000/v1`.
20
+ 2. Завантажує глобальні налаштування OMLX з середовища виконання через Rust.
21
+ 3. Якщо завантаження успішне, застосовує API ключ до внутрішнього стану.
22
+ 4. Якщо локальне сховище відсутнє, застосовує URL та модель з глобальних налаштувань.
23
+ 5. Якщо URL відповідає локальному замовленню, виконується перенаправлення через проксі myllm, що є тимчасовим перевизначенням.
24
+ 6. Зберігає поточні значення URL та моделі у локальне сховище.
25
+
26
+ ## Гарантії поведінки
27
+
28
+ - Перехоплює помилки і не пропускає винятків назовні (fail-safe).
29
+ - За певних помилок повертає порожнє значення (напр. `null`) замість винятку.
30
+ - Кешує результати в межах одного прогону.
@@ -0,0 +1,31 @@
1
+ ---
2
+ docgen:
3
+ source: npm/src/vue/use-updater.js
4
+ crc: c988fd96
5
+ model: omlx/gemma-4-e4b-it-OptiQ-4bit
6
+ score: 100
7
+ issues: judge:inaccurate:0.95
8
+ judgeModel: openai-codex/gpt-5.4-mini
9
+ ---
10
+
11
+ # use-updater.js
12
+
13
+ ## Огляд
14
+
15
+ Модуль забезпечує перевірку наявності новіших версій застосунку та ініціює процес оновлення. Публічна функція `useUpdater` виконує цю логіку, забезпечуючи перехоплення помилок (fail-safe) та запобігаючи виняткам назовні. Логіка роботи залежить від конфігураційних файлів: tauri.conf.json та default.json.
16
+
17
+ ## Поведінка
18
+
19
+ 1. При виклику `useUpdater` у середовищі розробки (dev builds) функціонал оновлення не виконується.
20
+ 2. При монтуванні компонента, через `FIRST_CHECK_DELAY_MS` часу, викликається перевірка на наявність оновлення.
21
+ 3. Після першої перевірки, функція `useUpdater` запускає періодичну перевірку на наявність оновлення кожні `CHECK_INTERVAL_MS` часу.
22
+ 4. При виклику перевірки на оновлення, якщо виявлено доступну новішу версію, відображається діалогове вікно з пропозицією встановити оновлення.
23
+ 5. Якщо користувач підтверджує встановлення, запускається процес завантаження та встановлення оновлення. Під час завантаження відображається прогрес.
24
+ 6. Після успішного встановлення оновлення, відображається діалогове вікно з пропозицією негайного перезапуску.
25
+ 7. Якщо користувач підтверджує перезапуск, виконується перезапуск застосунку.
26
+ 8. У разі будь-якої помилки під час перевірки або встановлення, користувач не отримує винятків, а замість цього відображається відповідне повідомлення або логується помилка.
27
+ 9. При демонтуванні компонента, періодичні таймери перериваються.
28
+
29
+ ## Гарантії поведінки
30
+
31
+ - Перехоплює помилки і не пропускає винятків назовні (fail-safe).
package/src/vue/index.js CHANGED
@@ -3,7 +3,9 @@
3
3
  // Requires the host app to provide vue + @tauri-apps/* (peer deps) and the
4
4
  // tauri-plugin-agent backend commands.
5
5
 
6
+ export { useAcpAgent } from './use-acp-agent.js'
6
7
  export { useAgent } from './use-agent.js'
7
8
  export { useOmlx } from './use-omlx.js'
9
+ export { useUpdater } from './use-updater.js'
8
10
  export { createTauriJournalStore } from './journal-store-tauri.js'
9
11
  export { tauriTransport } from './transports.js'
@@ -0,0 +1,109 @@
1
+ import { computed, ref } from 'vue'
2
+ import { acpConfig, startAcpMcpBridge } from '../core/acp-agent.js'
3
+ import { createAcpAgentKit } from '../core/acp-kit.js'
4
+ import { createTauriJournalStore } from './journal-store-tauri.js'
5
+ import { tauriTransport } from './transports.js'
6
+
7
+ // In-app ACP agent gateway — the ACP-flavored sibling of `useAgent()` (which
8
+ // stays on the old omlx/runAgent path). Binds an app's catalog to
9
+ // createAcpAgentKit and resolves two independent defaults per SPEC/plan:
10
+ //
11
+ // - which AGENT (codex/claude/cursor/pi) — per-machine, from `ACP_DEFAULT_AGENT`
12
+ // (via `acp_config()`), since different developers have different CLIs
13
+ // installed; the human can still override `agentKind.value` in the UI.
14
+ // - which MODEL — the app-owned MIN/AVG/MAX abstraction: each entry in
15
+ // `agents[kind].tiers` is a concrete preset (e.g. `codex.tiers.MAX` = the
16
+ // "ChatGPT 5.6 Sol" args/env). A caller can request a tier per call
17
+ // (`request(intent, { modelTier: 'MAX' })`); otherwise `defaultTier` applies.
18
+ //
19
+ // The domain MCP bridge is started once (`loadEnv()`) and its URL is reused
20
+ // for every spawned session, mirroring how `useOmlx().loadEnv()` resolves the
21
+ // omlx base URL once and reuses it.
22
+
23
+ const DEFAULT_TIER = 'AVG'
24
+
25
+ /**
26
+ * @param {object} config gateway config
27
+ * @param {object[]} config.catalog app tool catalog (required — passed to the domain MCP bridge)
28
+ * @param {Record<string, {command: string, args?: string[], env?: Record<string,string>, tiers: Record<string, {label: string, args?: string[], env?: Record<string,string>}>}>} config.agents per-agent-kind spawn presets, keyed by 'codex'|'claude'|'cursor'|'pi'
29
+ * @param {string} [config.defaultTier] fallback modelTier when a request doesn't specify one (default 'AVG')
30
+ * @param {string} config.cwd session working directory (absolute path)
31
+ * @param {Record<string, number>} [config.actorTiers] max executable tier rank per actor kind
32
+ * @param {(tool: object, input: object) => unknown} [config.transport] tool transport (default Tauri invoke)
33
+ * @returns {object} in-app ACP agent gateway
34
+ */
35
+ export function useAcpAgent({ catalog, agents = {}, defaultTier = DEFAULT_TIER, cwd, actorTiers, transport = tauriTransport } = {}) {
36
+ const defaultAgentKind = ref(null)
37
+ const agentKind = ref(null)
38
+ const modelTier = ref(defaultTier)
39
+ const mcpBridgeUrl = ref(null)
40
+ const journal = createTauriJournalStore()
41
+ const kit = createAcpAgentKit({ catalog, journal, transport, actorTiers })
42
+
43
+ /**
44
+ * Read the per-machine default agent (`ACP_DEFAULT_AGENT`) and start the
45
+ * domain MCP bridge. Call once before the first `request()` — mirrors
46
+ * `useOmlx().loadEnv()`. No-op-safe outside Tauri (tests / web): falls back
47
+ * to the first configured agent and leaves the MCP bridge unset.
48
+ * @returns {Promise<void>} resolves once defaults are resolved
49
+ */
50
+ async function loadEnv() {
51
+ const configuredKinds = Object.keys(agents)
52
+ try {
53
+ const cfg = await acpConfig()
54
+ defaultAgentKind.value = cfg.defaultAgentKind && agents[cfg.defaultAgentKind] ? cfg.defaultAgentKind : (configuredKinds[0] ?? null)
55
+ }
56
+ catch {
57
+ defaultAgentKind.value = configuredKinds[0] ?? null
58
+ }
59
+ if (!agentKind.value) agentKind.value = defaultAgentKind.value
60
+
61
+ if (catalog?.length) {
62
+ try {
63
+ mcpBridgeUrl.value = await startAcpMcpBridge(catalog)
64
+ }
65
+ catch {
66
+ mcpBridgeUrl.value = null
67
+ }
68
+ }
69
+ }
70
+
71
+ /**
72
+ * Build `createAcpSession` args for the currently selected agent + tier.
73
+ * @returns {object} spawn args
74
+ */
75
+ function resolveSpawnArgs() {
76
+ const preset = agents[agentKind.value]
77
+ if (!preset) throw new Error(`useAcpAgent: no preset configured for agent "${agentKind.value}"`)
78
+ const tier = preset.tiers?.[modelTier.value]
79
+ return {
80
+ agentKind: agentKind.value,
81
+ command: preset.command,
82
+ args: [...(preset.args ?? []), ...(tier?.args ?? [])],
83
+ env: { ...preset.env, ...tier?.env },
84
+ cwd,
85
+ mcpBridgeUrl: mcpBridgeUrl.value ?? undefined,
86
+ }
87
+ }
88
+
89
+ return {
90
+ agentKind,
91
+ modelTier,
92
+ defaultAgentKind,
93
+ availableAgentKinds: computed(() => Object.keys(agents)),
94
+ availableTiers: computed(() => Object.entries(agents[agentKind.value]?.tiers ?? {}).map(([id, t]) => ({ id, label: t.label ?? id }))),
95
+ loadEnv,
96
+ journal,
97
+ /**
98
+ * @param {string} intent user prompt
99
+ * @param {{modelTier?: string}} [opts] per-call overrides
100
+ * @returns {Promise<object>} structured result envelope
101
+ */
102
+ request: (intent, opts = {}) => {
103
+ if (opts.modelTier) modelTier.value = opts.modelTier
104
+ return kit.request({ intent, agent: resolveSpawnArgs() })
105
+ },
106
+ respond: (requestId, message) => kit.respond({ requestId, message }),
107
+ approve: (requestId, approve) => kit.approve({ requestId, approve }),
108
+ }
109
+ }
@@ -0,0 +1,116 @@
1
+ import { onMounted, onUnmounted } from 'vue'
2
+ import { relaunch } from '@tauri-apps/plugin-process'
3
+ import { check } from '@tauri-apps/plugin-updater'
4
+ import { useQuasar } from 'quasar'
5
+
6
+ // Checks for an app update on mount and hourly thereafter, prompting via a
7
+ // Quasar dialog; after install, offers an immediate relaunch. Requires the
8
+ // host app's tauri.conf.json to configure plugins.updater (pubkey + endpoint)
9
+ // and capabilities/default.json to grant "updater:default" — without the
10
+ // capability, check() fails with a silent permission-denied that only surfaces
11
+ // via console.error (no dialog, no visible error).
12
+ //
13
+ // No-op in dev builds: tauri.conf.json's version is the CI-injected release
14
+ // version, not what's running locally, so the updater would always think dev
15
+ // code is stale.
16
+
17
+ const FIRST_CHECK_DELAY_MS = 3000
18
+ const CHECK_INTERVAL_MS = 60 * 60 * 1000
19
+
20
+ /**
21
+ * @returns {void}
22
+ */
23
+ export function useUpdater() {
24
+ if (import.meta.env.DEV) return
25
+
26
+ const $q = useQuasar()
27
+ let timer = null
28
+ // A dialog is showing or an install already ran — don't stack background checks.
29
+ let busy = false
30
+
31
+ /**
32
+ * Asks the configured update endpoint for a newer version and, if found,
33
+ * walks the user through the install flow.
34
+ * @returns {Promise<void>}
35
+ */
36
+ async function checkForUpdates() {
37
+ if (busy) return
38
+ try {
39
+ const update = await check()
40
+ if (!update) return
41
+
42
+ busy = true
43
+ $q.dialog({
44
+ title: 'Доступне оновлення',
45
+ message: `Версія ${update.version} готова. Встановити зараз?`,
46
+ cancel: { label: 'Пізніше', flat: true },
47
+ ok: { label: 'Встановити', color: 'primary' },
48
+ persistent: true,
49
+ })
50
+ .onOk(() => installAndRelaunch(update))
51
+ .onCancel(() => {
52
+ busy = false
53
+ })
54
+ }
55
+ catch (error) {
56
+ // No network, or the updater isn't configured/permitted — don't bother
57
+ // the user, but leave a trace for diagnosis.
58
+ console.error('[updater] check failed:', error)
59
+ }
60
+ }
61
+
62
+ /**
63
+ * Downloads and installs the update with progress, then offers a relaunch.
64
+ * @param {import('@tauri-apps/plugin-updater').Update} update the update found by check()
65
+ * @returns {Promise<void>}
66
+ */
67
+ async function installAndRelaunch(update) {
68
+ let downloaded = 0
69
+ let total = 0
70
+ const dismiss = $q.notify({ group: false, timeout: 0, spinner: true, message: 'Завантаження оновлення…' })
71
+ try {
72
+ await update.downloadAndInstall(event => {
73
+ switch (event.event) {
74
+ case 'Started': {
75
+ total = event.data.contentLength ?? 0
76
+ break
77
+ }
78
+ case 'Progress': {
79
+ downloaded += event.data.chunkLength
80
+ if (total) dismiss({ message: `Завантаження… ${Math.round((downloaded / total) * 100)}%` })
81
+ break
82
+ }
83
+ case 'Finished': {
84
+ dismiss()
85
+ break
86
+ }
87
+ // No default
88
+ }
89
+ })
90
+ // busy stays true: the update is already on disk, a repeat check would
91
+ // only offer to install the same thing again.
92
+ $q.dialog({
93
+ title: 'Оновлення встановлено',
94
+ message: `Перезапустити зараз, щоб перейти на версію ${update.version}?`,
95
+ cancel: { label: 'Пізніше', flat: true },
96
+ ok: { label: 'Перезапустити', color: 'primary' },
97
+ persistent: true,
98
+ }).onOk(() => relaunch())
99
+ }
100
+ catch (error) {
101
+ dismiss()
102
+ busy = false
103
+ console.error('[updater] install failed:', error)
104
+ $q.notify({ message: `Помилка оновлення: ${error}`, color: 'negative', timeout: 5000 })
105
+ }
106
+ }
107
+
108
+ onMounted(() => {
109
+ setTimeout(checkForUpdates, FIRST_CHECK_DELAY_MS)
110
+ timer = setInterval(checkForUpdates, CHECK_INTERVAL_MS)
111
+ })
112
+
113
+ onUnmounted(() => {
114
+ if (timer) clearInterval(timer)
115
+ })
116
+ }