kiokuko-dsh 0.2.2 → 0.2.4

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 (147) hide show
  1. package/README.ja.md +4 -5
  2. package/README.md +5 -5
  3. package/dist/client.cjs +225 -159
  4. package/dist/context/continuity-view.d.ts +1 -1
  5. package/dist/dsh/coding-workflow/contracts.d.ts +120 -0
  6. package/dist/dsh/coding-workflow/contracts.d.ts.map +1 -0
  7. package/dist/dsh/coding-workflow/contracts.js +77 -0
  8. package/dist/dsh/coding-workflow/contracts.js.map +1 -0
  9. package/dist/dsh/coding-workflow/host.d.ts +41 -0
  10. package/dist/dsh/coding-workflow/host.d.ts.map +1 -0
  11. package/dist/dsh/coding-workflow/host.js +235 -0
  12. package/dist/dsh/coding-workflow/host.js.map +1 -0
  13. package/dist/dsh/coding-workflow/intent.d.ts +15 -0
  14. package/dist/dsh/coding-workflow/intent.d.ts.map +1 -0
  15. package/dist/dsh/coding-workflow/intent.js +86 -0
  16. package/dist/dsh/coding-workflow/intent.js.map +1 -0
  17. package/dist/dsh/coding-workflow/service.d.ts +155 -0
  18. package/dist/dsh/coding-workflow/service.d.ts.map +1 -0
  19. package/dist/dsh/coding-workflow/service.js +282 -0
  20. package/dist/dsh/coding-workflow/service.js.map +1 -0
  21. package/dist/dsh/coding-workflow/store.d.ts +17 -0
  22. package/dist/dsh/coding-workflow/store.d.ts.map +1 -0
  23. package/dist/dsh/coding-workflow/store.js +77 -0
  24. package/dist/dsh/coding-workflow/store.js.map +1 -0
  25. package/dist/dsh/completion-verifiers.d.ts +14 -1
  26. package/dist/dsh/completion-verifiers.d.ts.map +1 -1
  27. package/dist/dsh/completion-verifiers.js.map +1 -1
  28. package/dist/dsh/core/host.d.ts.map +1 -1
  29. package/dist/dsh/core/host.js +48 -7
  30. package/dist/dsh/core/host.js.map +1 -1
  31. package/dist/dsh/core/index.js +2 -2
  32. package/dist/dsh/core/index.js.map +1 -1
  33. package/dist/dsh/core/tasks.d.ts +2 -0
  34. package/dist/dsh/core/tasks.d.ts.map +1 -1
  35. package/dist/dsh/core/tasks.js +37 -2
  36. package/dist/dsh/core/tasks.js.map +1 -1
  37. package/dist/dsh/execution-selection.d.ts +1 -1
  38. package/dist/dsh/host-adapter/admission.d.ts.map +1 -1
  39. package/dist/dsh/host-adapter/admission.js +13 -22
  40. package/dist/dsh/host-adapter/admission.js.map +1 -1
  41. package/dist/dsh/host-adapter/boundaries.d.ts.map +1 -1
  42. package/dist/dsh/host-adapter/boundaries.js +2 -0
  43. package/dist/dsh/host-adapter/boundaries.js.map +1 -1
  44. package/dist/dsh/host-adapter/context.d.ts.map +1 -1
  45. package/dist/dsh/host-adapter/context.js +18 -13
  46. package/dist/dsh/host-adapter/context.js.map +1 -1
  47. package/dist/dsh/host-adapter/lifecycle.d.ts.map +1 -1
  48. package/dist/dsh/host-adapter/lifecycle.js +12 -0
  49. package/dist/dsh/host-adapter/lifecycle.js.map +1 -1
  50. package/dist/dsh/host-adapter/routing.js +1 -1
  51. package/dist/dsh/host-adapter/routing.js.map +1 -1
  52. package/dist/dsh/host-adapter.d.ts.map +1 -1
  53. package/dist/dsh/host-adapter.js +36 -6
  54. package/dist/dsh/host-adapter.js.map +1 -1
  55. package/dist/dsh/lisp/candidate.d.ts +2 -2
  56. package/dist/dsh/lisp/code-intelligence-contracts.d.ts +1 -1
  57. package/dist/dsh/lisp/coding-choice.d.ts +3 -1
  58. package/dist/dsh/lisp/coding-choice.d.ts.map +1 -1
  59. package/dist/dsh/lisp/coding-choice.js +17 -12
  60. package/dist/dsh/lisp/coding-choice.js.map +1 -1
  61. package/dist/dsh/lisp/manager.d.ts +1 -0
  62. package/dist/dsh/lisp/manager.d.ts.map +1 -1
  63. package/dist/dsh/lisp/manager.js +13 -0
  64. package/dist/dsh/lisp/manager.js.map +1 -1
  65. package/dist/dsh/lisp/request-surface.d.ts +12 -2
  66. package/dist/dsh/lisp/request-surface.d.ts.map +1 -1
  67. package/dist/dsh/lisp/request-surface.js +1 -1
  68. package/dist/dsh/lisp/request-surface.js.map +1 -1
  69. package/dist/dsh/lisp/surface.d.ts.map +1 -1
  70. package/dist/dsh/lisp/surface.js +46 -5
  71. package/dist/dsh/lisp/surface.js.map +1 -1
  72. package/dist/dsh/lisp-service-key.d.ts +9 -0
  73. package/dist/dsh/lisp-service-key.d.ts.map +1 -1
  74. package/dist/dsh/lisp-service-key.js +11 -0
  75. package/dist/dsh/lisp-service-key.js.map +1 -1
  76. package/dist/dsh/models/profiles.d.ts +2 -0
  77. package/dist/dsh/models/profiles.d.ts.map +1 -1
  78. package/dist/dsh/models/profiles.js +9 -5
  79. package/dist/dsh/models/profiles.js.map +1 -1
  80. package/dist/dsh/models/service.d.ts +24 -1
  81. package/dist/dsh/models/service.d.ts.map +1 -1
  82. package/dist/dsh/models/service.js +85 -42
  83. package/dist/dsh/models/service.js.map +1 -1
  84. package/dist/dsh/modules/lisp.d.ts.map +1 -1
  85. package/dist/dsh/modules/lisp.js +1 -12
  86. package/dist/dsh/modules/lisp.js.map +1 -1
  87. package/dist/dsh/modules/resources.d.ts +3 -1
  88. package/dist/dsh/modules/resources.d.ts.map +1 -1
  89. package/dist/dsh/modules/resources.js +4 -0
  90. package/dist/dsh/modules/resources.js.map +1 -1
  91. package/dist/dsh/node-tap-summary.d.ts +2 -0
  92. package/dist/dsh/node-tap-summary.d.ts.map +1 -1
  93. package/dist/dsh/node-tap-summary.js +6 -1
  94. package/dist/dsh/node-tap-summary.js.map +1 -1
  95. package/dist/dsh/on-demand-intake.d.ts.map +1 -1
  96. package/dist/dsh/on-demand-intake.js +13 -4
  97. package/dist/dsh/on-demand-intake.js.map +1 -1
  98. package/dist/dsh/owned-evidence.d.ts.map +1 -1
  99. package/dist/dsh/owned-evidence.js +2 -2
  100. package/dist/dsh/owned-evidence.js.map +1 -1
  101. package/dist/dsh/owned-execution.d.ts +1 -0
  102. package/dist/dsh/owned-execution.d.ts.map +1 -1
  103. package/dist/dsh/owned-execution.js +37 -2
  104. package/dist/dsh/owned-execution.js.map +1 -1
  105. package/dist/dsh/skill-prompts.json +1 -1
  106. package/dist/dsh/task-completion-host.js +3 -3
  107. package/dist/dsh/task-completion-host.js.map +1 -1
  108. package/dist/dsh/task-completion.d.ts +16 -0
  109. package/dist/dsh/task-completion.d.ts.map +1 -1
  110. package/dist/dsh/task-completion.js +130 -24
  111. package/dist/dsh/task-completion.js.map +1 -1
  112. package/dist/dsh/task-intake.d.ts.map +1 -1
  113. package/dist/dsh/task-intake.js +7 -0
  114. package/dist/dsh/task-intake.js.map +1 -1
  115. package/dist/enno-oduno/coding-workflow.d.ts +39 -0
  116. package/dist/enno-oduno/coding-workflow.d.ts.map +1 -0
  117. package/dist/enno-oduno/coding-workflow.js +33 -0
  118. package/dist/enno-oduno/coding-workflow.js.map +1 -0
  119. package/dist/enno-oduno/schemas.d.ts +2 -2
  120. package/dist/enno-oduno/store.d.ts.map +1 -1
  121. package/dist/enno-oduno/store.js +46 -3
  122. package/dist/enno-oduno/store.js.map +1 -1
  123. package/dist/enno-oduno/types.d.ts +1 -0
  124. package/dist/enno-oduno/types.d.ts.map +1 -1
  125. package/dist/enno-oduno/verifier.d.ts.map +1 -1
  126. package/dist/enno-oduno/verifier.js +4 -1
  127. package/dist/enno-oduno/verifier.js.map +1 -1
  128. package/dist/locale/en.json +1 -1
  129. package/dist/locale/ja.json +1 -1
  130. package/dist/locale/ko.json +1 -1
  131. package/dist/locale/zh-CN.json +1 -1
  132. package/dist/model-tools/contracts.d.ts +2 -2
  133. package/dist/models-client.cjs +223 -157
  134. package/dist/models-client.d.ts.map +1 -1
  135. package/dist/models-client.js +261 -166
  136. package/dist/models-client.js.map +1 -1
  137. package/docs/coding-workflow.md +45 -0
  138. package/docs/execution-support.md +4 -0
  139. package/docs/kiokuko-models.md +25 -13
  140. package/docs/lisp-hot-tools.md +2 -2
  141. package/docs/lisp.md +7 -9
  142. package/migrations/036_coding_workflow.sql +26 -0
  143. package/package.json +2 -2
  144. package/skills/coding-ideal-routine-skill/SKILL.md +6 -0
  145. package/skills/kiokuko-lisp/SKILL.md +5 -1
  146. package/skills/kiokuko-soul/SKILL.md +2 -2
  147. package/skills/one-shot-software-completion/SKILL.md +5 -6
package/README.ja.md CHANGED
@@ -88,8 +88,8 @@ DSH 更新後に Kiokuko を読み込めない場合は、[起動失敗時の復
88
88
  - Arch Linux: `sudo pacman -S sbcl`
89
89
 
90
90
  `~/.dsh/profiles/web/cordis.patch.yml` の `kiokuko-dsh` 行に次を追加し(他の `config` 値は保持)、
91
- プラグインを再読み込みすると、最初の実装・不具合修正の前に Lisp モードを使うか確認します。
92
- 選択はセッション内で保持します。`/kioku-lisp enable` でも有効にできます。
91
+ プラグインを再読み込みすると、実装タスクごとに Goal・実装項目・観測可能な条件を示してから Lisp モードを使うか確認します。
92
+ 選択はそのタスクと範囲に保存し、新しいタスクでは再確認します。`/kioku-lisp enable` は明示的な手動切替です。
93
93
  読み込まれた設定は `dsh --profile web --dump-config` で確認できます。
94
94
 
95
95
  ```yaml
@@ -101,9 +101,8 @@ DSH 更新後に Kiokuko を読み込めない場合は、[起動失敗時の復
101
101
  ```
102
102
 
103
103
  既定の開発モードでは Bubblewrap は不要です。Linux で明示的に保護互換モードを選ぶ場合に必要です。
104
- Lisp を選ぶと、Lisp 用ツールで通常実行します。役小角を使う場合は「Lispモードを使わない」を選んでください。
105
- 自由入力は相談・訂正として AI に渡します。
106
- 通常の編集・テストには追加確認を求めません。ソース・実データの削除と既存の永続DB変更は対象を確認します。Lisp と通常ツールを併用でき、Lisp の障害でも通常の開発は継続できます。[独自実行、レシート、記憶の再利用](docs/owned-execution.md)を参照してください。
104
+ 「使う」は Lisp、「使わない」は通常ツール、「取消・作業を保持」は準備内容を残して取消です。閉じる・未回答では実装を始めません。通常実行/役小角の選択は別に保持します。Lisp の起動失敗はブロッカーとして残し、復旧または明示的な経路変更後に再開します。
105
+ 選択後の通常の編集・テストには追加確認を求めません。ソース・実データの削除と既存の永続DB変更は対象を確認します。各項目の最新の証拠と、通常の利用入口からの最終確認が揃った場合だけ完了します。[Goal 駆動コーディング](docs/coding-workflow.md)と[独自実行、レシート、記憶の再利用](docs/owned-execution.md)を参照してください。
107
106
  [設定、API、停止・復旧方法](docs/lisp.md)を参照してください。
108
107
  永続 Lisp では、`kioku.code` からディスク上のコードの構造と読み取り専用の LSP 結果を取得できます。V1 service を提供する任意の provider が必要です。公開済みの `dsh-lsp-server` v0.1.12 は未対応なので、現時点では[ローカルの provider 修正](patches/code-intelligence/README.md)を使います。[API と上限](docs/lisp.md#read-only-code-intelligence)を確認してください。
109
108
 
package/README.md CHANGED
@@ -89,8 +89,9 @@ Install SBCL first:
89
89
  - Arch Linux: `sudo pacman -S sbcl`
90
90
 
91
91
  Add this to the `kiokuko-dsh` row in `~/.dsh/profiles/web/cordis.patch.yml`
92
- (keep other `config` values), then reload the plugin. The first implementation or
93
- debugging request asks whether to use Lisp; the session retains your choice.
92
+ (keep other `config` values), then reload the plugin. Each implementation task
93
+ shows its Goal, items and observable checks before asking whether to use Lisp.
94
+ The choice belongs to that task and scope; a new task asks again.
94
95
  You can also enable it with `/kioku-lisp enable`.
95
96
  Check the loaded configuration with `dsh --profile web --dump-config`.
96
97
 
@@ -103,9 +104,8 @@ Check the loaded configuration with `dsh --profile web --dump-config`.
103
104
  ```
104
105
 
105
106
  The default development mode does not require Bubblewrap. The explicit protected compatibility mode does on Linux.
106
- Choosing Lisp starts normal execution with the Lisp tools. Choose not to use Lisp
107
- if you want Enno. Free text is passed to the AI as a discussion or correction.
108
- Ordinary edits and tests run without confirmation. Source/data deletion and existing durable user database mutation require a concrete review. Lisp and ordinary tools coexist; worker failures leave ordinary development available. See [owned execution, receipts and memory reuse](docs/owned-execution.md).
107
+ Choose “使う” to use Lisp, “使わない” to use ordinary tools, or “取消・作業を保持” to cancel while preserving prepared work. Closing the question leaves implementation pending. Lisp choice and normal/Enno selection are separate. A failed Lisp startup remains a recoverable blocker until the selected route works or you explicitly change it.
108
+ Ordinary edits and tests run without further confirmation after that choice. Source/data deletion and existing durable user database mutation require a concrete review. Lisp and ordinary tools coexist. Completion requires current item evidence and a fresh final check through the user’s entry point. See [Goal-driven coding](docs/coding-workflow.md) and [owned execution, receipts and memory reuse](docs/owned-execution.md).
109
109
  See [setup, APIs, limits and recovery](docs/lisp.md).
110
110
  Persistent Lisp can optionally inspect parser-backed disk snapshots and read-only
111
111
  LSP results through `kioku.code`. The provider must advertise V1; published
package/dist/client.cjs CHANGED
@@ -66,6 +66,7 @@ window.__ModuleLoader__.load({
66
66
  ollama: ["Ollama", "http://localhost:11434/v1", "chat-completions"],
67
67
  custom: ["Custom connection", "http://localhost:8080/v1", "chat-completions"]
68
68
  };
69
+ var OAUTH_KINDS = ["codex", "claude", "xai", "openai", "openrouter", "nous"];
69
70
  async function modelsApi(body, query = "") {
70
71
  const response = await fetch("/api/kiokuko.models" + query, {
71
72
  ...body ? {
@@ -90,6 +91,7 @@ window.__ModuleLoader__.load({
90
91
  reasoning: false,
91
92
  image: false
92
93
  });
94
+ const [advanced, setAdvanced] = useState(false), [manualOpen, setManualOpen] = useState(false);
93
95
  const operation = useRef(void 0), mounted = useRef(true), working = useRef(false);
94
96
  const sessionId = props.sessionId;
95
97
  const load = async () => {
@@ -131,12 +133,15 @@ window.__ModuleLoader__.load({
131
133
  setError("");
132
134
  setModels([]);
133
135
  try {
134
- setModels(await modelsApi(void 0, "?op=models&id=" + encodeURIComponent(c.id)));
136
+ const list = await modelsApi(void 0, "?op=models&id=" + encodeURIComponent(c.id));
137
+ setModels(list);
138
+ return list;
135
139
  } catch (e) {
136
140
  setError(messageOf(e));
141
+ return [];
137
142
  }
138
143
  };
139
- const save = async () => {
144
+ const persist = async () => {
140
145
  await modelsApi({
141
146
  op: "save",
142
147
  connection: {
@@ -148,11 +153,33 @@ window.__ModuleLoader__.load({
148
153
  serviceTier: connection.serviceTier,
149
154
  models: connection.models
150
155
  },
151
- revision: state.revision
156
+ revision: (await load()).revision
152
157
  });
153
- const next = await load();
154
- await choose(next.connections.find((c) => c.id === connection.id));
155
- setNotice("Connection saved");
158
+ };
159
+ const reopen = async () => {
160
+ const saved = await load();
161
+ return choose(saved.connections.find((c) => c.id === connection.id) ?? connection);
162
+ };
163
+ const connect = async () => {
164
+ const draft = { ...connection };
165
+ await persist();
166
+ const typed = key.trim();
167
+ if (typed) {
168
+ await modelsApi({ op: "key", id: draft.id, key: typed });
169
+ setKey("");
170
+ }
171
+ let failure = "";
172
+ try {
173
+ await modelsApi({ op: "refresh", id: draft.id });
174
+ } catch (e) {
175
+ failure = messageOf(e);
176
+ }
177
+ const list = await reopen();
178
+ if (failure) {
179
+ setNotice(typed ? "Connection and key saved" : "Connection saved");
180
+ setError(failure + " Register a model manually if this endpoint stays unusable.");
181
+ } else
182
+ setNotice(list.length ? "Connected \xB7 " + list.length + " model(s)" : "Connected; no models discovered yet");
156
183
  };
157
184
  const newConnection = (kind) => {
158
185
  const spec = MODEL_CONNECTION_DEFAULTS[kind];
@@ -168,10 +195,11 @@ window.__ModuleLoader__.load({
168
195
  setModels([]);
169
196
  setKey("");
170
197
  setError("");
198
+ setNotice("");
171
199
  };
172
200
  const update = (field, value) => setConnection({ ...connection, [field]: value });
173
201
  const startLogin = async () => {
174
- await save();
202
+ await persist();
175
203
  const result = await modelsApi({ op: "login", id: connection.id });
176
204
  operation.current = result.operationId;
177
205
  setAuth({ id: result.operationId, status: "pending", events: [] });
@@ -187,10 +215,9 @@ window.__ModuleLoader__.load({
187
215
  setAuth(next);
188
216
  if (next.status !== "pending") {
189
217
  operation.current = void 0;
190
- void load().then((value) => {
191
- if (next.status === "success")
192
- return choose(value.connections.find((c) => c.id === connection.id));
193
- setError(next.error ?? "Authentication cancelled");
218
+ void reopen().then(() => {
219
+ if (next.status !== "success")
220
+ setError(next.error ?? "Authentication cancelled");
194
221
  }).catch((e) => setError(messageOf(e)));
195
222
  }
196
223
  }, (e) => {
@@ -203,7 +230,7 @@ window.__ModuleLoader__.load({
203
230
  clearInterval(timer);
204
231
  };
205
232
  }, [auth?.id, auth?.status]);
206
- const input = (label, value, onChange, type = "text") => jsx("label", {
233
+ const input = (label, value, onChange, type = "text", submit) => jsx("label", {
207
234
  children: jsxs(Fragment, {
208
235
  children: [
209
236
  jsx("span", { children: label }),
@@ -213,6 +240,14 @@ window.__ModuleLoader__.load({
213
240
  "aria-label": label,
214
241
  disabled: busy || label === "Base URL" && ["codex", "opencode", "opencode-go"].includes(connection?.kind),
215
242
  onChange: (e) => onChange(e.target.value),
243
+ ...submit ? {
244
+ onKeyDown: (e) => {
245
+ if (e.key !== "Enter")
246
+ return;
247
+ e.preventDefault();
248
+ submit();
249
+ }
250
+ } : {},
216
251
  autoComplete: type === "password" ? "new-password" : "off"
217
252
  })
218
253
  ]
@@ -233,9 +268,9 @@ window.__ModuleLoader__.load({
233
268
  jsx("p", {
234
269
  children: "Connect directly for chat, Enno and Deep. Credentials are shared with dsh-cli. Signing out also signs dsh-cli out."
235
270
  }),
236
- ...error ? [jsx("p", { role: "alert", children: error })] : [],
237
- ...notice ? [jsx("p", { role: "status", children: notice })] : [],
238
- ...busy ? [jsx("p", { role: "status", children: "Working\u2026" })] : [],
271
+ ...error ? [jsx("p", { role: "alert", children: error }, "error")] : [],
272
+ ...notice ? [jsx("p", { role: "status", children: notice }, "notice")] : [],
273
+ ...busy ? [jsx("p", { role: "status", children: "Working\u2026" }, "busy")] : [],
239
274
  button("Reload", () => void run(load)),
240
275
  jsx("label", {
241
276
  children: jsxs(Fragment, {
@@ -262,99 +297,35 @@ window.__ModuleLoader__.load({
262
297
  ...connection ? [
263
298
  jsxs("div", {
264
299
  className: "kiokuko-models-editor",
300
+ key: "editor",
265
301
  children: [
266
- input("Connection name", connection.name, (value) => update("name", value)),
267
- input("Base URL", connection.baseURL, (value) => update("baseURL", value)),
268
- jsx("label", {
269
- children: jsxs(Fragment, {
270
- children: [
271
- "Protocol",
272
- jsx("select", {
273
- "aria-label": "Protocol",
274
- value: connection.protocol,
275
- disabled: busy || [
276
- "codex",
277
- "infron",
278
- "opencode",
279
- "opencode-go"
280
- ].includes(connection.kind),
281
- onChange: (e) => update("protocol", e.target.value),
282
- children: [
283
- ["chat-completions", "Chat Completions"],
284
- ["responses", "Responses"],
285
- ["messages", "Messages"]
286
- ].map(([id, name]) => jsx("option", { value: id, children: name }, id))
287
- })
288
- ]
289
- })
290
- }),
291
- ...connection.kind === "infron" ? [
292
- jsx("label", {
293
- children: jsxs(Fragment, {
294
- children: [
295
- "Service tier",
296
- jsx("select", {
297
- "aria-label": "Service tier",
298
- value: connection.serviceTier,
299
- disabled: busy,
300
- onChange: (e) => update("serviceTier", e.target.value),
301
- children: [
302
- jsx("option", {
303
- value: "standard",
304
- children: "Standard"
305
- }),
306
- jsx("option", {
307
- value: "flex",
308
- children: "Flex"
309
- })
310
- ]
311
- })
312
- ]
302
+ jsxs("h3", {
303
+ children: [
304
+ connection.name,
305
+ jsx("span", {
306
+ className: "kiokuko-models-state",
307
+ children: " \xB7 " + (connection.authState ?? "not saved yet")
313
308
  })
314
- }),
315
- jsx("p", {
316
- children: "Requested tier: " + connection.serviceTier + ". Last request: " + (connection.lastRequestedTier ?? "none") + ". Actual served tier: " + (connection.actualTier ?? "unknown") + ". Infron may serve Standard for a Flex request."
317
- })
318
- ] : [],
319
- button("Save connection", () => void run(save)),
309
+ ]
310
+ }),
320
311
  ...connection.kind !== "codex" && connection.kind !== "ollama" ? [
321
- input("API key / bearer token", key, setKey, "password"),
322
- button("Save key", () => void run(async () => {
323
- await save();
324
- await modelsApi({
325
- op: "key",
326
- id: connection.id,
327
- key
328
- });
329
- setKey("");
330
- await load();
331
- await choose(connection);
332
- setNotice("Key saved");
333
- }), !key)
334
- ] : [],
335
- ...[
336
- "codex",
337
- "claude",
338
- "xai",
339
- "openai",
340
- "openrouter",
341
- "nous"
342
- ].includes(connection.kind) ? [
343
- button("Log in", () => void run(startLogin), auth?.status === "pending")
312
+ input("API key / bearer token", key, setKey, "password", () => {
313
+ if (!busy && key.trim())
314
+ void run(connect);
315
+ })
344
316
  ] : [],
345
- button("Log out (also dsh-cli)", () => void run(async () => {
346
- await modelsApi({ op: "logout", id: connection.id });
347
- setKey("");
348
- setModels([]);
349
- await load();
350
- setNotice("Signed out");
351
- })),
352
- button("Refresh models", () => void run(async () => {
353
- await modelsApi({ op: "refresh", id: connection.id });
354
- const next = await load();
355
- await choose(next.connections.find((c) => c.id === connection.id));
356
- setNotice("Models refreshed");
357
- })),
317
+ jsxs("div", {
318
+ className: "kiokuko-models-actions",
319
+ children: [
320
+ button("Save and connect", () => void run(connect)),
321
+ ...OAUTH_KINDS.includes(connection.kind) ? [
322
+ button("Log in", () => void run(startLogin), auth?.status === "pending")
323
+ ] : []
324
+ ]
325
+ }),
326
+ jsx("p", {
327
+ children: connection.kind === "ollama" ? "Ollama needs no key. Save and connect to list its models." : "Paste the API key and press Enter, or use Save and connect. The key is stored with dsh-cli's shared credentials."
328
+ }),
358
329
  ...auth?.status === "pending" ? [
359
330
  jsxs("div", {
360
331
  "aria-label": "Authentication",
@@ -443,61 +414,156 @@ window.__ModuleLoader__.load({
443
414
  ]
444
415
  })
445
416
  ] : [],
446
- ...!["opencode", "opencode-go"].includes(connection.kind) ? [
447
- jsx("details", {
448
- children: jsxs(Fragment, {
449
- children: [
450
- jsx("summary", {
451
- children: "Register model manually"
452
- }),
453
- input("Model ID", manual.id, (value) => setManual({ ...manual, id: value })),
454
- input("Context window", manual.contextWindow, (value) => setManual({
455
- ...manual,
456
- contextWindow: Number(value)
457
- }), "number"),
458
- input("Maximum output tokens", manual.maxTokens, (value) => setManual({
459
- ...manual,
460
- maxTokens: Number(value)
461
- }), "number"),
462
- jsx("label", {
463
- children: jsxs(Fragment, {
417
+ jsxs("details", {
418
+ open: advanced,
419
+ children: [
420
+ jsx("summary", {
421
+ onClick: (e) => {
422
+ e.preventDefault();
423
+ setAdvanced(!advanced);
424
+ },
425
+ children: "Advanced settings"
426
+ }),
427
+ input("Connection name", connection.name, (value) => update("name", value)),
428
+ input("Base URL", connection.baseURL, (value) => update("baseURL", value)),
429
+ jsx("label", {
430
+ children: jsxs(Fragment, {
431
+ children: [
432
+ "Protocol",
433
+ jsx("select", {
434
+ "aria-label": "Protocol",
435
+ value: connection.protocol,
436
+ disabled: busy || [
437
+ "codex",
438
+ "infron",
439
+ "opencode",
440
+ "opencode-go"
441
+ ].includes(connection.kind),
442
+ onChange: (e) => update("protocol", e.target.value),
464
443
  children: [
465
- jsx("input", {
466
- type: "checkbox",
467
- checked: manual.reasoning,
468
- onChange: (e) => setManual({
469
- ...manual,
470
- reasoning: e.target.checked
471
- })
472
- }),
473
- "Reasoning supported"
474
- ]
444
+ ["chat-completions", "Chat Completions"],
445
+ ["responses", "Responses"],
446
+ ["messages", "Messages"]
447
+ ].map(([id, name]) => jsx("option", { value: id, children: name }, id))
475
448
  })
476
- }),
477
- jsx("label", {
478
- children: jsxs(Fragment, {
479
- children: [
480
- jsx("input", {
481
- type: "checkbox",
482
- checked: manual.image,
483
- onChange: (e) => setManual({
484
- ...manual,
485
- image: e.target.checked
449
+ ]
450
+ })
451
+ }),
452
+ ...connection.kind === "infron" ? [
453
+ jsx("label", {
454
+ children: jsxs(Fragment, {
455
+ children: [
456
+ "Service tier",
457
+ jsx("select", {
458
+ "aria-label": "Service tier",
459
+ value: connection.serviceTier,
460
+ disabled: busy,
461
+ onChange: (e) => update("serviceTier", e.target.value),
462
+ children: [
463
+ jsx("option", {
464
+ value: "standard",
465
+ children: "Standard"
466
+ }),
467
+ jsx("option", {
468
+ value: "flex",
469
+ children: "Flex"
486
470
  })
487
- }),
488
- "Image input supported"
489
- ]
490
- })
491
- }),
492
- button("Add manual model", () => {
493
- update("models", [
494
- ...connection.models.filter((m) => m.id !== manual.id),
495
- { ...manual, name: manual.id }
496
- ]);
497
- setNotice("Model added to draft. Save connection to register it.");
498
- }, !manual.id)
499
- ]
500
- })
471
+ ]
472
+ })
473
+ ]
474
+ })
475
+ }),
476
+ jsx("p", {
477
+ children: "Requested tier: " + connection.serviceTier + ". Last request: " + (connection.lastRequestedTier ?? "none") + ". Actual served tier: " + (connection.actualTier ?? "unknown") + ". Infron may serve Standard for a Flex request."
478
+ })
479
+ ] : [],
480
+ button("Save connection", () => void run(async () => {
481
+ await persist();
482
+ await reopen();
483
+ setNotice("Connection saved");
484
+ })),
485
+ button("Refresh models", () => void run(async () => {
486
+ await persist();
487
+ await modelsApi({ op: "refresh", id: connection.id });
488
+ const list = await reopen();
489
+ setNotice(list.length ? "Models refreshed" : "Models refreshed; none discovered");
490
+ })),
491
+ button("Log out (also dsh-cli)", () => void run(async () => {
492
+ await persist();
493
+ await modelsApi({ op: "logout", id: connection.id });
494
+ setKey("");
495
+ setModels([]);
496
+ await load();
497
+ setNotice("Signed out");
498
+ })),
499
+ ...!["opencode", "opencode-go"].includes(connection.kind) ? [
500
+ jsx("details", {
501
+ open: manualOpen,
502
+ children: jsxs(Fragment, {
503
+ children: [
504
+ jsx("summary", {
505
+ onClick: (e) => {
506
+ e.preventDefault();
507
+ setManualOpen(!manualOpen);
508
+ },
509
+ children: "Register model manually"
510
+ }),
511
+ input("Model ID", manual.id, (value) => setManual({ ...manual, id: value })),
512
+ input("Context window", manual.contextWindow, (value) => setManual({
513
+ ...manual,
514
+ contextWindow: Number(value)
515
+ }), "number"),
516
+ input("Maximum output tokens", manual.maxTokens, (value) => setManual({
517
+ ...manual,
518
+ maxTokens: Number(value)
519
+ }), "number"),
520
+ jsx("label", {
521
+ children: jsxs(Fragment, {
522
+ children: [
523
+ jsx("input", {
524
+ type: "checkbox",
525
+ checked: manual.reasoning,
526
+ onChange: (e) => setManual({
527
+ ...manual,
528
+ reasoning: e.target.checked
529
+ })
530
+ }),
531
+ "Reasoning supported"
532
+ ]
533
+ })
534
+ }),
535
+ jsx("label", {
536
+ children: jsxs(Fragment, {
537
+ children: [
538
+ jsx("input", {
539
+ type: "checkbox",
540
+ checked: manual.image,
541
+ onChange: (e) => setManual({
542
+ ...manual,
543
+ image: e.target.checked
544
+ })
545
+ }),
546
+ "Image input supported"
547
+ ]
548
+ })
549
+ }),
550
+ button("Add manual model", () => {
551
+ update("models", [
552
+ ...connection.models.filter((m) => m.id !== manual.id),
553
+ { ...manual, name: manual.id }
554
+ ]);
555
+ setNotice("Model added to draft. Save connection to register it.");
556
+ }, !manual.id)
557
+ ]
558
+ })
559
+ })
560
+ ] : []
561
+ ]
562
+ }),
563
+ jsx("h4", { children: "Models" }),
564
+ ...models.length === 0 ? [
565
+ jsx("p", {
566
+ children: "No models yet. Save and connect to discover them, or register one under Advanced settings."
501
567
  })
502
568
  ] : [],
503
569
  input("Search models", filter, setFilter),
@@ -588,7 +654,7 @@ window.__ModuleLoader__.load({
588
654
  }, "kiokuko models focus lifecycle");
589
655
  ctx.effect(() => {
590
656
  const style = document.createElement("style");
591
- style.textContent = ".kiokuko-models-modal{width:min(900px,calc(100vw - 32px))}.kiokuko-models-panel{box-sizing:border-box;width:100%;max-width:900px;padding:16px;overflow:auto;max-height:75vh}.kiokuko-models-panel label{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin:12px 0}.kiokuko-models-panel input,.kiokuko-models-panel select{max-width:100%;box-sizing:border-box;border:1px solid #888;border-radius:6px;padding:8px;color:inherit;background:transparent}.kiokuko-models-panel button{border:1px solid #888;border-radius:6px;padding:8px;margin:4px;color:inherit}.kiokuko-models-panel button:disabled{opacity:.5}.kiokuko-models-panel li{margin:8px 0}.kiokuko-models-panel :focus-visible{outline:2px solid #3286ff;outline-offset:3px}";
657
+ style.textContent = ".kiokuko-models-modal{width:min(900px,calc(100vw - 32px))}.kiokuko-models-panel{box-sizing:border-box;width:100%;max-width:900px;padding:16px;overflow:auto;max-height:75vh}.kiokuko-models-panel label{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin:12px 0}.kiokuko-models-panel input,.kiokuko-models-panel select{max-width:100%;box-sizing:border-box;border:1px solid #888;border-radius:6px;padding:8px;color:inherit;background:transparent}.kiokuko-models-panel button{border:1px solid #888;border-radius:6px;padding:8px;margin:4px;color:inherit}.kiokuko-models-panel button:disabled{opacity:.5}.kiokuko-models-panel li{margin:8px 0}.kiokuko-models-panel :focus-visible{outline:2px solid #3286ff;outline-offset:3px}.kiokuko-models-panel summary{cursor:pointer;margin:12px 0}.kiokuko-models-panel h3,.kiokuko-models-panel h4{margin:12px 0 0}.kiokuko-models-state{font-weight:400;font-size:.85em;opacity:.75}.kiokuko-models-actions{display:flex;gap:8px;align-items:center;flex-wrap:wrap}";
592
658
  document.head.append(style);
593
659
  return () => style.remove();
594
660
  }, "kiokuko models style");
@@ -1060,7 +1126,7 @@ window.__ModuleLoader__.load({
1060
1126
  setItems(data.items);
1061
1127
  setError("");
1062
1128
  for (const item of data.items)
1063
- if ((item.kind === "report" || notices) && !item.delivered && !seen.current.has(item.id)) {
1129
+ if ((item.kind === "report" || notices && !item.id.startsWith("completion-wait:")) && !item.delivered && !seen.current.has(item.id)) {
1064
1130
  seen.current.add(item.id);
1065
1131
  setOpen(true);
1066
1132
  }
@@ -1525,7 +1591,7 @@ window.__ModuleLoader__.load({
1525
1591
  ] }),
1526
1592
  jsx("p", { id: `${titleId}-keys`, children: pending.review ? "\u56DE\u7B54\u6E08\u307F\u306E\u5185\u5BB9\u3067\u3059\u3002Enter\u3067\u6B21\u306E\u8CEA\u554F\u3092\u8868\u793A\u3001Esc\u3067\u9589\u3058\u307E\u3059\u3002" : hint }),
1527
1593
  jsxs("div", { className: "kiokuko-intake-body", children: [
1528
- reviewing ? jsx(MarkdownText, { text: question.detail, labels: reviewCopy.labels }) : question.detail ? jsx("p", { children: question.detail }) : null,
1594
+ reviewing ? jsx(MarkdownText, { text: question.detail, labels: reviewCopy.labels }) : question.detail ? jsx("p", { children: question.detail, ...question.id.startsWith("coding-lisp-") ? { "data-coding-goal": true, style: { whiteSpace: "pre-wrap", overflowWrap: "anywhere" } } : {} }) : null,
1529
1595
  !pending.review && !snapshot.closed && snapshot.state === "continued" ? jsx("p", { children: "\u51E6\u7406\u306F\u7D99\u7D9A\u4E2D\u3067\u3059\u3002\u3053\u306E\u8CEA\u554F\u306B\u306F\u5F8C\u304B\u3089\u56DE\u7B54\u3067\u304D\u307E\u3059\u3002" }) : null,
1530
1596
  snapshot.countdown ? jsx("p", { children: `\u56DE\u7B54\u5F85\u3061: ${Math.ceil(snapshot.countdown.remainingMs / 1e3)}\u79D2${snapshot.countdown.running ? "" : "\uFF08\u64CD\u4F5C\u4E2D\u306F\u505C\u6B62\uFF09"}` }) : null,
1531
1597
  pending.review ? jsx("p", { children: `\u56DE\u7B54\u6E08\u307F: ${pending.review.find((a) => a.id === question.id)?.selected.join("\u3001") ?? ""} ${pending.review.find((a) => a.id === question.id)?.custom ?? ""}` }) : null,
@@ -25,8 +25,8 @@ declare const ownerSchema: z.ZodObject<{
25
25
  workspace: z.ZodString;
26
26
  sessionId: z.ZodString;
27
27
  mode: z.ZodEnum<{
28
- normal: "normal";
29
28
  enno: "enno";
29
+ normal: "normal";
30
30
  }>;
31
31
  workUnitId: z.ZodNullable<z.ZodString>;
32
32
  role: z.ZodNullable<z.ZodString>;