@7n/tauri-components 0.10.1 → 0.11.1

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 (64) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/package.json +1 -4
  3. package/src/components/AgentDialog.vue +21 -46
  4. package/src/components/AuditDialog.vue +9 -17
  5. package/src/components/BaseDialog.vue +2 -6
  6. package/src/components/DialogActions.vue +2 -3
  7. package/src/components/RequestView.vue +2 -3
  8. package/src/components/StatePill.vue +1 -1
  9. package/src/components/docs/AgentDialog.md +4 -4
  10. package/src/components/docs/AuditDialog.md +4 -4
  11. package/src/components/docs/BaseDialog.md +4 -4
  12. package/src/components/docs/DialogActions.md +4 -4
  13. package/src/components/docs/RequestView.md +4 -4
  14. package/src/components/docs/StatePill.md +4 -4
  15. package/src/components/docs/index.md +4 -4
  16. package/src/components/docs/status.md +4 -4
  17. package/src/components/index.js +2 -2
  18. package/src/components/status.js +1 -1
  19. package/src/core/acp-agent-presets.js +2 -2
  20. package/src/core/acp-agent.js +21 -15
  21. package/src/core/acp-kit.js +79 -30
  22. package/src/core/dispatch.js +3 -3
  23. package/src/core/docs/acp-agent-presets.md +4 -4
  24. package/src/core/docs/acp-agent.md +4 -4
  25. package/src/core/docs/acp-kit.md +4 -4
  26. package/src/core/docs/dispatch.md +4 -4
  27. package/src/core/docs/manifest.md +4 -4
  28. package/src/core/manifest.js +10 -8
  29. package/src/docs/index.md +4 -4
  30. package/src/index.js +3 -8
  31. package/src/testing/docs/quasar.md +4 -4
  32. package/src/testing/quasar.js +2 -2
  33. package/src/vue/docs/index.md +4 -4
  34. package/src/vue/docs/journal-store-tauri.md +4 -4
  35. package/src/vue/docs/use-acp-agent.md +4 -4
  36. package/src/vue/docs/use-updater.md +4 -4
  37. package/src/vue/index.js +4 -6
  38. package/src/vue/journal-store-tauri.js +2 -2
  39. package/src/vue/use-acp-agent.js +22 -14
  40. package/src/vue/use-updater.js +4 -6
  41. package/types/core/dispatch.d.ts +5 -2
  42. package/types/core/manifest.d.ts +14 -9
  43. package/types/core/scope.d.ts +24 -11
  44. package/types/core/tools.d.ts +1 -1
  45. package/types/index.d.ts +4 -9
  46. package/src/core/agent-handler.js +0 -171
  47. package/src/core/agent-kit.js +0 -43
  48. package/src/core/docs/agent-handler.md +0 -31
  49. package/src/core/docs/agent-kit.md +0 -25
  50. package/src/core/docs/llm.md +0 -29
  51. package/src/core/docs/omlx-models.md +0 -30
  52. package/src/core/docs/resolve-omlx-base-url.md +0 -40
  53. package/src/core/llm.js +0 -90
  54. package/src/core/omlx-models.js +0 -34
  55. package/src/core/resolve-omlx-base-url.js +0 -84
  56. package/src/vue/docs/use-agent.md +0 -29
  57. package/src/vue/docs/use-omlx.md +0 -30
  58. package/src/vue/use-agent.js +0 -60
  59. package/src/vue/use-omlx.js +0 -102
  60. package/types/core/agent-handler.d.ts +0 -43
  61. package/types/core/agent-kit.d.ts +0 -30
  62. package/types/core/llm.d.ts +0 -52
  63. package/types/core/omlx-models.d.ts +0 -17
  64. package/types/core/resolve-omlx-base-url.d.ts +0 -42
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.11.1] - 2026-07-18
4
+
5
+ ### Changed
6
+
7
+ - rules
8
+
9
+ ## [0.11.0] - 2026-07-17
10
+
11
+ ### Removed
12
+
13
+ - useAgent()/createAgentKit (omlx/runAgent chat-completion шлях) видалено — `useAcpAgent()`/`createAcpAgentKit` (ACP: спавн codex/claude/cursor/pi) тепер єдиний агентний шлях. Разом з ним прибрано `core/llm.js`, `core/agent-handler.js`, `core/omlx-models.js`, `core/resolve-omlx-base-url.js`, `vue/use-omlx.js` та Rust-команду `omlx_config` (tauri-plugin-agent)
14
+
3
15
  ## [0.10.1] - 2026-07-16
4
16
 
5
17
  ### Changed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@7n/tauri-components",
3
- "version": "0.10.1",
3
+ "version": "0.11.1",
4
4
  "type": "module",
5
5
  "description": "Shared LLM agent engine + Vue/Quasar UI for Tauri apps (chat, journal, trust-tier approval).",
6
6
  "license": "MIT",
@@ -46,9 +46,6 @@
46
46
  "peerDependenciesMeta": {
47
47
  "@tauri-apps/api": { "optional": true },
48
48
  "@tauri-apps/plugin-http": { "optional": true },
49
- "@tauri-apps/plugin-process": { "optional": true },
50
- "@tauri-apps/plugin-updater": { "optional": true },
51
- "@vue/test-utils": { "optional": true },
52
49
  "quasar": { "optional": true }
53
50
  },
54
51
  "knip": {
@@ -3,33 +3,26 @@
3
3
  @update:model-value="val => emit('update:modelValue', val)"
4
4
  @show="onShow"
5
5
  :model-value="modelValue"
6
- title="Agent (local LLM)"
6
+ title="Agent"
7
7
  icon="sym_o_smart_toy"
8
8
  :width="560"
9
- body-class="q-gutter-sm"
10
- >
9
+ body-class="q-gutter-sm">
11
10
  <template #header>
12
- <q-btn @click="showConfig = !showConfig" icon="sym_o_tune" flat round dense size="sm" title="omlx config" />
11
+ <q-btn @click="showConfig = !showConfig" icon="sym_o_tune" flat round dense size="sm" title="agent config" />
13
12
  </template>
14
13
 
15
14
  <template v-if="showConfig">
16
- <q-input v-model="baseUrl" dense outlined label="omlx base URL" />
15
+ <q-select v-model="agentKind" :options="availableAgentKinds" dense outlined label="agent" />
17
16
  <q-select
18
- v-model="model"
19
- :options="models"
20
- @filter="(_, update) => update()"
21
- :loading="modelsLoading"
22
- use-input
23
- fill-input
24
- hide-selected
25
- input-debounce="0"
26
- new-value-mode="add-unique"
17
+ v-model="modelTier"
18
+ :options="availableTiers"
19
+ option-value="id"
20
+ option-label="label"
21
+ emit-value
22
+ map-options
27
23
  dense
28
24
  outlined
29
- label="model"
30
- hint="завантажені моделі omlx; можна вписати свою"
31
- />
32
- <q-input v-model="apiKey" dense outlined label="API key" type="password" />
25
+ label="tier" />
33
26
  <q-separator class="q-my-sm" />
34
27
  </template>
35
28
 
@@ -38,9 +31,7 @@
38
31
  <div v-if="turn.role === 'user'" class="chat-user">{{ turn.text }}</div>
39
32
  <RequestView v-else :result="turn.result" />
40
33
  </template>
41
- <div v-if="running" class="chat-thinking">
42
- <q-spinner-dots size="18px" /> думаю…
43
- </div>
34
+ <div v-if="running" class="chat-thinking"><q-spinner-dots size="18px" /> думаю…</div>
44
35
  </div>
45
36
 
46
37
  <q-input
@@ -52,8 +43,7 @@
52
43
  type="textarea"
53
44
  autogrow
54
45
  :label="inputLabel"
55
- :hint="promptHint"
56
- />
46
+ :hint="promptHint" />
57
47
 
58
48
  <!-- jscpd:ignore-start — formal footer markup; jscpd html-mode aligns its
59
49
  attribute tokens with an unrelated import block (no shared logic) -->
@@ -64,8 +54,7 @@
64
54
  :submit-label="sendLabel"
65
55
  icon="sym_o_play_arrow"
66
56
  :disable="sendDisabled"
67
- :loading="running"
68
- />
57
+ :loading="running" />
69
58
  </template>
70
59
  <!-- jscpd:ignore-end -->
71
60
  </BaseDialog>
@@ -78,17 +67,17 @@ import BaseDialog from './BaseDialog.vue'
78
67
  import DialogActions from './DialogActions.vue'
79
68
  import RequestView from './RequestView.vue'
80
69
 
81
- // The agent gateway is injected by the host app (`useAgent({ catalog, … })` from
82
- // @7n/tauri-components/vue), so this dialog stays domain-free and testable.
70
+ // The agent gateway is injected by the host app (`useAcpAgent({ catalog, … })`
71
+ // from @7n/tauri-components/vue), so this dialog stays domain-free and testable.
83
72
  const props = defineProps({
84
73
  modelValue: { type: Boolean, default: false },
85
74
  agent: { type: Object, required: true },
86
- promptHint: { type: String, default: 'наприклад: Create a task named deploy in /Users/.../mt, agent mode' },
75
+ promptHint: { type: String, default: 'наприклад: Create a task named deploy in /Users/.../mt, agent mode' }
87
76
  })
88
77
  const emit = defineEmits(['update:modelValue', 'ran'])
89
78
 
90
79
  const $q = useQuasar()
91
- const { baseUrl, model, apiKey, saveOmlx, loadOmlxEnv, listModels, request, respond } = props.agent
80
+ const { agentKind, modelTier, availableAgentKinds, availableTiers, loadEnv, request, respond } = props.agent
92
81
 
93
82
  const prompt = ref('')
94
83
  const running = ref(false)
@@ -96,8 +85,6 @@ const turns = ref([])
96
85
  const requestId = ref(null)
97
86
  const logEl = ref(null)
98
87
  const showConfig = ref(false)
99
- const models = ref([])
100
- const modelsLoading = ref(false)
101
88
 
102
89
  // Labels shift once a conversation is under way (fresh request → follow-up).
103
90
  const inputLabel = computed(() => (turns.value.length ? 'Повідомлення' : 'Prompt'))
@@ -105,23 +92,13 @@ const sendLabel = computed(() => (turns.value.length ? 'Надіслати' : '
105
92
  const sendDisabled = computed(() => running.value || !prompt.value.trim())
106
93
 
107
94
  /**
108
- * Pull omlx config from the user's global settings; reset the conversation.
95
+ * Resolve the per-machine default agent + start the domain MCP bridge; reset the conversation.
109
96
  */
110
97
  async function onShow() {
111
98
  prompt.value = ''
112
99
  turns.value = []
113
100
  requestId.value = null
114
- await loadOmlxEnv()
115
- // Populate the model dropdown from the omlx server (best-effort; stays editable).
116
- if (listModels) {
117
- modelsLoading.value = true
118
- try {
119
- models.value = await listModels()
120
- }
121
- finally {
122
- modelsLoading.value = false
123
- }
124
- }
101
+ await loadEnv()
125
102
  }
126
103
 
127
104
  /**
@@ -154,12 +131,10 @@ async function send() {
154
131
  scrollToEnd()
155
132
  running.value = true
156
133
  try {
157
- saveOmlx()
158
134
  apply(await (requestId.value ? respond(requestId.value, text) : request(text)))
159
135
  } catch (error) {
160
136
  $q.notify({ type: 'negative', message: String(error?.message ?? error) })
161
- }
162
- finally {
137
+ } finally {
163
138
  running.value = false
164
139
  }
165
140
  }
@@ -6,8 +6,7 @@
6
6
  title="Request journal"
7
7
  icon="sym_o_history"
8
8
  :width="680"
9
- body-class=""
10
- >
9
+ body-class="">
11
10
  <template #header>
12
11
  <q-btn @click="refresh" icon="sym_o_refresh" flat round dense size="sm" :loading="loading" title="Refresh" />
13
12
  </template>
@@ -36,8 +35,7 @@
36
35
  color="negative"
37
36
  unelevated
38
37
  no-caps
39
- :loading="busyId === rec.id"
40
- />
38
+ :loading="busyId === rec.id" />
41
39
  <q-btn @click="onApprove(rec, false)" label="Відхилити" flat no-caps :disable="busyId === rec.id" />
42
40
  </div>
43
41
  </div>
@@ -57,7 +55,7 @@ import StatePill from './StatePill.vue'
57
55
  // keeping this dialog domain-free.
58
56
  const props = defineProps({
59
57
  modelValue: { type: Boolean, default: false },
60
- agent: { type: Object, required: true },
58
+ agent: { type: Object, required: true }
61
59
  })
62
60
  const emit = defineEmits(['update:modelValue', 'changed'])
63
61
 
@@ -84,11 +82,9 @@ async function refresh() {
84
82
  loading.value = true
85
83
  try {
86
84
  records.value = await journal.list()
87
- }
88
- catch (error) {
85
+ } catch (error) {
89
86
  $q.notify({ type: 'negative', message: String(error?.message ?? error) })
90
- }
91
- finally {
87
+ } finally {
92
88
  loading.value = false
93
89
  }
94
90
  }
@@ -111,11 +107,9 @@ async function onRespond(rec, message) {
111
107
  await respond(rec.id, message)
112
108
  await refresh()
113
109
  emit('changed')
114
- }
115
- catch (error) {
110
+ } catch (error) {
116
111
  $q.notify({ type: 'negative', message: String(error?.message ?? error) })
117
- }
118
- finally {
112
+ } finally {
119
113
  busyId.value = null
120
114
  }
121
115
  }
@@ -131,11 +125,9 @@ async function onApprove(rec, ok) {
131
125
  await approve(rec.id, ok)
132
126
  await refresh()
133
127
  emit('changed')
134
- }
135
- catch (error) {
128
+ } catch (error) {
136
129
  $q.notify({ type: 'negative', message: String(error?.message ?? error) })
137
- }
138
- finally {
130
+ } finally {
139
131
  busyId.value = null
140
132
  }
141
133
  }
@@ -1,9 +1,5 @@
1
1
  <template>
2
- <q-dialog
3
- @update:model-value="value => emit('update:modelValue', value)"
4
- v-bind="$attrs"
5
- :model-value="modelValue"
6
- >
2
+ <q-dialog @update:model-value="value => emit('update:modelValue', value)" v-bind="$attrs" :model-value="modelValue">
7
3
  <q-card class="base-dialog" :style="{ width: `${width}px` }">
8
4
  <q-card-section class="row items-center no-wrap q-pb-sm">
9
5
  <q-icon v-if="icon" :name="icon" size="20px" class="q-mr-sm" />
@@ -40,7 +36,7 @@ defineProps({
40
36
  title: { type: String, required: true },
41
37
  icon: { type: String, default: '' },
42
38
  width: { type: Number, default: 520 },
43
- bodyClass: { type: String, default: 'q-gutter-md' },
39
+ bodyClass: { type: String, default: 'q-gutter-md' }
44
40
  })
45
41
  const emit = defineEmits(['update:modelValue'])
46
42
  </script>
@@ -8,8 +8,7 @@
8
8
  :loading="loading"
9
9
  color="primary"
10
10
  unelevated
11
- no-caps
12
- />
11
+ no-caps />
13
12
  </template>
14
13
 
15
14
  <script setup>
@@ -20,7 +19,7 @@ defineProps({
20
19
  submitLabel: { type: String, required: true },
21
20
  icon: { type: String, default: undefined },
22
21
  disable: { type: Boolean, default: false },
23
- loading: { type: Boolean, default: false },
22
+ loading: { type: Boolean, default: false }
24
23
  })
25
24
  const emit = defineEmits(['submit'])
26
25
  </script>
@@ -11,8 +11,7 @@
11
11
  <q-icon
12
12
  :name="action.envelope?.ok ? 'sym_o_check_circle' : 'sym_o_error'"
13
13
  :color="action.envelope?.ok ? 'positive' : 'negative'"
14
- size="14px"
15
- />
14
+ size="14px" />
16
15
  <code>{{ action.tool }}({{ JSON.stringify(action.input) }})</code>
17
16
  </div>
18
17
  </div>
@@ -23,7 +22,7 @@
23
22
  import StatePill from './StatePill.vue'
24
23
 
25
24
  defineProps({
26
- result: { type: Object, required: true },
25
+ result: { type: Object, required: true }
27
26
  })
28
27
  </script>
29
28
 
@@ -11,7 +11,7 @@
11
11
  import { statusColor } from './status.js'
12
12
 
13
13
  defineProps({
14
- status: { type: String, required: true },
14
+ status: { type: String, required: true }
15
15
  })
16
16
  </script>
17
17
 
@@ -1,12 +1,12 @@
1
1
  ---
2
+ type: Vue Component
3
+ title: AgentDialog.vue
4
+ resource: npm/src/components/AgentDialog.vue
2
5
  docgen:
3
- source: npm/src/components/AgentDialog.vue
4
- crc: 197cc9c0
6
+ crc: aa14e51b
5
7
  model: omlx/gemma-4-e4b-it-OptiQ-4bit
6
8
  ---
7
9
 
8
- # AgentDialog.vue
9
-
10
10
  Компонент відображає діалогове вікно для взаємодії з локальною мовною моделлю (LLM) через агент. Він дозволяє користувачеві вводити запити, налаштовувати конфігурацію агента та бачити історію чату.
11
11
 
12
12
  ## Поведінка
@@ -1,12 +1,12 @@
1
1
  ---
2
+ type: Vue Component
3
+ title: AuditDialog.vue
4
+ resource: npm/src/components/AuditDialog.vue
2
5
  docgen:
3
- source: npm/src/components/AuditDialog.vue
4
- crc: 963a61d8
6
+ crc: 8c440daf
5
7
  model: omlx/gemma-4-e4b-it-OptiQ-4bit
6
8
  ---
7
9
 
8
- # AuditDialog.vue
9
-
10
10
  Компонент відображає журнал аудиту, наданий зовнішнім агентом. Він дозволяє переглядати записи, розширювати їх для детального огляду та взаємодіяти з ними (наприклад, відповідати або затверджувати).
11
11
 
12
12
  ## Поведінка
@@ -1,12 +1,12 @@
1
1
  ---
2
+ type: Vue Component
3
+ title: BaseDialog.vue
4
+ resource: npm/src/components/BaseDialog.vue
2
5
  docgen:
3
- source: npm/src/components/BaseDialog.vue
4
- crc: 88aaae5f
6
+ crc: fd761cd0
5
7
  model: omlx/gemma-4-e4b-it-OptiQ-4bit
6
8
  ---
7
9
 
8
- # BaseDialog.vue
9
-
10
10
  Компонент надає універсальну структуру для діалогових вікон у застосунку. Він інкапсулює типовий макет діалогу, включаючи заголовок, тіло та кнопки дій.
11
11
 
12
12
  ## Поведінка
@@ -1,12 +1,12 @@
1
1
  ---
2
+ type: Vue Component
3
+ title: DialogActions.vue
4
+ resource: npm/src/components/DialogActions.vue
2
5
  docgen:
3
- source: npm/src/components/DialogActions.vue
4
- crc: 7126e317
6
+ crc: bccdf0c8
5
7
  model: omlx/gemma-4-e4b-it-OptiQ-4bit
6
8
  ---
7
9
 
8
- # DialogActions.vue
9
-
10
10
  Компонент надає стандартний нижній колонтитул для діалогових вікон, що містить кнопку скасування та основну кнопку дії. Він забезпечує канонічний патерн "скасувати + відправити" для діалогів.
11
11
 
12
12
  ## Поведінка
@@ -1,12 +1,12 @@
1
1
  ---
2
+ type: Vue Component
3
+ title: RequestView.vue
4
+ resource: npm/src/components/RequestView.vue
2
5
  docgen:
3
- source: npm/src/components/RequestView.vue
4
- crc: ce95caa9
6
+ crc: c56a396d
5
7
  model: omlx/gemma-4-e4b-it-OptiQ-4bit
6
8
  ---
7
9
 
8
- # RequestView.vue
9
-
10
10
  Компонент відображає детальний вигляд результату виконання запиту. Він візуалізує статус, резюме, помилки та список виконаних дій.
11
11
 
12
12
  ## Поведінка
@@ -1,12 +1,12 @@
1
1
  ---
2
+ type: Vue Component
3
+ title: StatePill.vue
4
+ resource: npm/src/components/StatePill.vue
2
5
  docgen:
3
- source: npm/src/components/StatePill.vue
4
- crc: ccee8975
6
+ crc: bc3d53e9
5
7
  model: omlx/gemma-4-e4b-it-OptiQ-4bit
6
8
  ---
7
9
 
8
- # StatePill.vue
9
-
10
10
  Компонент відображає візуальний маркер стану (pill). Він використовується для індикації статусу в різних частинах застосунку.
11
11
 
12
12
  ## Поведінка
@@ -1,14 +1,14 @@
1
1
  ---
2
+ type: JS Module
3
+ title: index.js
4
+ resource: npm/src/components/index.js
2
5
  docgen:
3
- source: npm/src/components/index.js
4
- crc: 42b50c52
6
+ crc: 6d136e3a
5
7
  model: omlx/gemma-4-e4b-it-OptiQ-4bit
6
8
  score: 100
7
9
  judgeModel: openai-codex/gpt-5.4-mini
8
10
  ---
9
11
 
10
- # index.js
11
-
12
12
  ## Огляд
13
13
 
14
14
  Компоненти цього файлу керують відображенням діалогових вікон, які взаємодіють з агентом. Експортується базовий клас для діалогів, компоненти для відображення специфічних дій, деталей запиту та поточного стану, а також константи для визначення кольорів стану.
@@ -1,15 +1,15 @@
1
1
  ---
2
+ type: JS Module
3
+ title: status.js
4
+ resource: npm/src/components/status.js
2
5
  docgen:
3
- source: npm/src/components/status.js
4
- crc: 352af502
6
+ crc: 7ef53fdd
5
7
  model: omlx/gemma-4-e4b-it-OptiQ-4bit
6
8
  score: 100
7
9
  issues: judge:inaccurate:0.96
8
10
  judgeModel: openai-codex/gpt-5.4-mini
9
11
  ---
10
12
 
11
- # status.js
12
-
13
13
  ## Огляд
14
14
 
15
15
  Файл визначає кольорові значення, що відповідають різним станам запиту. Публічні функції `STATUS_COLOR` та `statusColor` повертають конкретний акцентний колір для заданого статусу або сірий колір у випадку невідомого статусу.
@@ -1,6 +1,6 @@
1
1
  // `@7n/tauri-components/components` — Quasar dialogs for the agent. AgentDialog
2
- // and AuditDialog take the injected `agent` gateway (from ./vue useAgent) via a
3
- // prop; the rest are pure props-only building blocks. Requires the host app to
2
+ // and AuditDialog take the injected `agent` gateway (from ./vue useAcpAgent) via
3
+ // a prop; the rest are pure props-only building blocks. Requires the host app to
4
4
  // provide vue + quasar (peer deps) and to have Quasar installed.
5
5
 
6
6
  export { default as AgentDialog } from './AgentDialog.vue'
@@ -9,7 +9,7 @@ export const STATUS_COLOR = {
9
9
  needs_clarification: '#64d2ff',
10
10
  needs_approval: '#ff9f0a',
11
11
  failed: '#ff453a',
12
- rejected: '#8e8e93',
12
+ rejected: '#8e8e93'
13
13
  }
14
14
 
15
15
  const FALLBACK = '#8e8e93'
@@ -20,6 +20,6 @@ export const CODEX_ACP_AGENT_PRESET = {
20
20
  tiers: {
21
21
  MIN: { label: 'GPT-5.6 Luna', env: codexModelEnv('gpt-5.6-luna') },
22
22
  AVG: { label: 'GPT-5.6 Terra', env: codexModelEnv('gpt-5.6-terra') },
23
- MAX: { label: 'GPT-5.6 Sol', env: codexModelEnv('gpt-5.6-sol') },
24
- },
23
+ MAX: { label: 'GPT-5.6 Sol', env: codexModelEnv('gpt-5.6-sol') }
24
+ }
25
25
  }
@@ -1,13 +1,11 @@
1
1
  import { invoke } from '@tauri-apps/api/core'
2
2
  import { listen } from '@tauri-apps/api/event'
3
3
 
4
- // ACP session driver: the replacement for llm.js's runAgent()/createOpenAiChat.
5
- // Instead of running our own chat-completion loop, we spawn an external ACP
6
- // agent (codex-acp/claude-agent-acp/cursor `agent acp`/pi-acp) via the Rust
7
- // plugin's acp_* commands and stream its `session/update` notifications back
8
- // into the same {content, trace, messages, stopped?} shape runAgent() used to
9
- // return, so agent-handler.js's runAndJournal needs no structural changes —
10
- // only which turn-runner it calls.
4
+ // ACP session driver: instead of running our own chat-completion loop, we
5
+ // spawn an external ACP agent (codex-acp/claude-agent-acp/cursor `agent acp`/
6
+ // pi-acp) via the Rust plugin's acp_* commands and stream its `session/update`
7
+ // notifications back into a {content, trace, messages, stopped?} shape that
8
+ // acp-kit.js's runAndJournal folds straight into the journal.
11
9
  //
12
10
  // Domain-tool approval (the MCP bridge's `acp://mcp-tool-call`) and native ACP
13
11
  // permission requests (`acp://permission-request`) are separate event streams
@@ -30,9 +28,18 @@ import { listen } from '@tauri-apps/api/event'
30
28
  * @param {boolean} [params.allowTerminal] grant terminal/*
31
29
  * @returns {Promise<{sessionKey: string, agentKind: string}>} session handle
32
30
  */
33
- export async function createAcpSession({ agentKind, command, args = [], env = {}, cwd, mcpBridgeUrl, allowFs = false, allowTerminal = false }) {
31
+ export async function createAcpSession({
32
+ agentKind,
33
+ command,
34
+ args = [],
35
+ env = {},
36
+ cwd,
37
+ mcpBridgeUrl,
38
+ allowFs = false,
39
+ allowTerminal = false
40
+ }) {
34
41
  const sessionKey = await invoke('plugin:agent|acp_spawn_agent', {
35
- args: { command, args, env, cwd, mcpBridgeUrl, allowFs, allowTerminal },
42
+ args: { command, args, env, cwd, mcpBridgeUrl, allowFs, allowTerminal }
36
43
  })
37
44
  return { sessionKey, agentKind }
38
45
  }
@@ -70,7 +77,7 @@ function applySessionUpdate(state, update) {
70
77
  state.calls.set(update.toolCallId, {
71
78
  tool: update.title ?? update.toolCallId,
72
79
  input: update.rawInput ?? {},
73
- envelope: null,
80
+ envelope: null
74
81
  })
75
82
  break
76
83
  }
@@ -100,7 +107,7 @@ function applySessionUpdate(state, update) {
100
107
  export async function runAcpTurn({ sessionKey, text, onChunk }) {
101
108
  const state = { text: '', messageId: null, calls: new Map() }
102
109
 
103
- const unlisten = await listen('acp://session-update', (event) => {
110
+ const unlisten = await listen('acp://session-update', event => {
104
111
  if (event.payload?.sessionKey !== sessionKey) return
105
112
  applySessionUpdate(state, event.payload.update)
106
113
  onChunk?.(event.payload.update)
@@ -115,10 +122,9 @@ export async function runAcpTurn({ sessionKey, text, onChunk }) {
115
122
  steps: 1,
116
123
  trace,
117
124
  messages,
118
- stopped: stoppedFromStopReason(stopReason),
125
+ stopped: stoppedFromStopReason(stopReason)
119
126
  }
120
- }
121
- finally {
127
+ } finally {
122
128
  unlisten()
123
129
  }
124
130
  }
@@ -175,7 +181,7 @@ export function respondAcpPermission(requestId, optionId) {
175
181
 
176
182
  /**
177
183
  * Register this app's tool catalog with the domain MCP bridge and start it.
178
- * @param {object[]} catalog tool definitions (same shape passed to `createAgentKit`)
184
+ * @param {object[]} catalog tool definitions (same shape passed to `createAcpAgentKit`)
179
185
  * @returns {Promise<string>} the bridge's loopback URL, e.g. `http://127.0.0.1:54321/`
180
186
  */
181
187
  export async function startAcpMcpBridge(catalog) {