@namzu/cli 20.0.0 → 22.0.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 (224) hide show
  1. package/CHANGELOG.md +371 -0
  2. package/README.md +71 -10
  3. package/dist/cli.d.ts.map +1 -1
  4. package/dist/cli.js +24 -2
  5. package/dist/cli.js.map +1 -1
  6. package/dist/commands/acp.d.ts.map +1 -1
  7. package/dist/commands/acp.js +6 -1
  8. package/dist/commands/acp.js.map +1 -1
  9. package/dist/commands/run-stream.d.ts.map +1 -1
  10. package/dist/commands/run-stream.js +9 -1
  11. package/dist/commands/run-stream.js.map +1 -1
  12. package/dist/commands/run.d.ts.map +1 -1
  13. package/dist/commands/run.js +15 -12
  14. package/dist/commands/run.js.map +1 -1
  15. package/dist/config/load.d.ts.map +1 -1
  16. package/dist/config/load.js +44 -2
  17. package/dist/config/load.js.map +1 -1
  18. package/dist/config/schema.d.ts +24 -13
  19. package/dist/config/schema.d.ts.map +1 -1
  20. package/dist/config/schema.js.map +1 -1
  21. package/dist/doctor/checks/chain.d.ts.map +1 -1
  22. package/dist/doctor/checks/chain.js +11 -5
  23. package/dist/doctor/checks/chain.js.map +1 -1
  24. package/dist/doctor/checks/credentials.d.ts.map +1 -1
  25. package/dist/doctor/checks/credentials.js +7 -1
  26. package/dist/doctor/checks/credentials.js.map +1 -1
  27. package/dist/index.d.ts +1 -1
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js.map +1 -1
  30. package/dist/installation.d.ts +5 -0
  31. package/dist/installation.d.ts.map +1 -0
  32. package/dist/installation.js +48 -0
  33. package/dist/installation.js.map +1 -0
  34. package/dist/integrations/providers/access.d.ts +7 -0
  35. package/dist/integrations/providers/access.d.ts.map +1 -0
  36. package/dist/integrations/providers/access.js +17 -0
  37. package/dist/integrations/providers/access.js.map +1 -0
  38. package/dist/integrations/providers/current-credential.d.ts +4 -0
  39. package/dist/integrations/providers/current-credential.d.ts.map +1 -0
  40. package/dist/integrations/providers/current-credential.js +45 -0
  41. package/dist/integrations/providers/current-credential.js.map +1 -0
  42. package/dist/integrations/providers/discover.d.ts +28 -54
  43. package/dist/integrations/providers/discover.d.ts.map +1 -1
  44. package/dist/integrations/providers/discover.js +62 -58
  45. package/dist/integrations/providers/discover.js.map +1 -1
  46. package/dist/integrations/providers/gemini-credentials.d.ts +13 -0
  47. package/dist/integrations/providers/gemini-credentials.d.ts.map +1 -0
  48. package/dist/integrations/providers/gemini-credentials.js +148 -0
  49. package/dist/integrations/providers/gemini-credentials.js.map +1 -0
  50. package/dist/integrations/providers/harness-credentials.d.ts +14 -0
  51. package/dist/integrations/providers/harness-credentials.d.ts.map +1 -1
  52. package/dist/integrations/providers/harness-credentials.js +46 -0
  53. package/dist/integrations/providers/harness-credentials.js.map +1 -1
  54. package/dist/integrations/providers/model-reasoning.d.ts +4 -0
  55. package/dist/integrations/providers/model-reasoning.d.ts.map +1 -0
  56. package/dist/integrations/providers/model-reasoning.js +46 -0
  57. package/dist/integrations/providers/model-reasoning.js.map +1 -0
  58. package/dist/integrations/providers/register.d.ts +1 -1
  59. package/dist/integrations/providers/register.d.ts.map +1 -1
  60. package/dist/integrations/providers/register.js +16 -1
  61. package/dist/integrations/providers/register.js.map +1 -1
  62. package/dist/integrations/providers/registry.d.ts +4 -4
  63. package/dist/integrations/providers/registry.d.ts.map +1 -1
  64. package/dist/integrations/providers/registry.js +33 -0
  65. package/dist/integrations/providers/registry.js.map +1 -1
  66. package/dist/integrations/providers/setup.d.ts +49 -0
  67. package/dist/integrations/providers/setup.d.ts.map +1 -0
  68. package/dist/integrations/providers/setup.js +105 -0
  69. package/dist/integrations/providers/setup.js.map +1 -0
  70. package/dist/integrations/sessions/context-inventory.d.ts +4 -0
  71. package/dist/integrations/sessions/context-inventory.d.ts.map +1 -0
  72. package/dist/integrations/sessions/context-inventory.js +44 -0
  73. package/dist/integrations/sessions/context-inventory.js.map +1 -0
  74. package/dist/integrations/sessions/conversation-search.d.ts +60 -0
  75. package/dist/integrations/sessions/conversation-search.d.ts.map +1 -0
  76. package/dist/integrations/sessions/conversation-search.js +461 -0
  77. package/dist/integrations/sessions/conversation-search.js.map +1 -0
  78. package/dist/integrations/sessions/store.d.ts +1 -0
  79. package/dist/integrations/sessions/store.d.ts.map +1 -1
  80. package/dist/integrations/sessions/store.js +17 -4
  81. package/dist/integrations/sessions/store.js.map +1 -1
  82. package/dist/integrations/sessions/task-context.d.ts +4 -0
  83. package/dist/integrations/sessions/task-context.d.ts.map +1 -0
  84. package/dist/integrations/sessions/task-context.js +73 -0
  85. package/dist/integrations/sessions/task-context.js.map +1 -0
  86. package/dist/integrations/subagents/activity.d.ts +3 -1
  87. package/dist/integrations/subagents/activity.d.ts.map +1 -1
  88. package/dist/integrations/subagents/activity.js +32 -5
  89. package/dist/integrations/subagents/activity.js.map +1 -1
  90. package/dist/integrations/subagents/history.d.ts +26 -0
  91. package/dist/integrations/subagents/history.d.ts.map +1 -0
  92. package/dist/integrations/subagents/history.js +76 -0
  93. package/dist/integrations/subagents/history.js.map +1 -0
  94. package/dist/integrations/subagents/model-effort.d.ts +4 -0
  95. package/dist/integrations/subagents/model-effort.d.ts.map +1 -0
  96. package/dist/integrations/subagents/model-effort.js +12 -0
  97. package/dist/integrations/subagents/model-effort.js.map +1 -0
  98. package/dist/integrations/subagents/runtime.d.ts +27 -7
  99. package/dist/integrations/subagents/runtime.d.ts.map +1 -1
  100. package/dist/integrations/subagents/runtime.js +305 -35
  101. package/dist/integrations/subagents/runtime.js.map +1 -1
  102. package/dist/integrations/web/search.d.ts +11 -0
  103. package/dist/integrations/web/search.d.ts.map +1 -0
  104. package/dist/integrations/web/search.js +73 -0
  105. package/dist/integrations/web/search.js.map +1 -0
  106. package/dist/memory/io.d.ts +12 -0
  107. package/dist/memory/io.d.ts.map +1 -0
  108. package/dist/memory/io.js +177 -0
  109. package/dist/memory/io.js.map +1 -0
  110. package/dist/memory/presentation.d.ts +4 -1
  111. package/dist/memory/presentation.d.ts.map +1 -1
  112. package/dist/memory/presentation.js +16 -2
  113. package/dist/memory/presentation.js.map +1 -1
  114. package/dist/memory/store.d.ts +17 -3
  115. package/dist/memory/store.d.ts.map +1 -1
  116. package/dist/memory/store.js +61 -35
  117. package/dist/memory/store.js.map +1 -1
  118. package/dist/output-schema.d.ts +4 -0
  119. package/dist/output-schema.d.ts.map +1 -0
  120. package/dist/output-schema.js +18 -0
  121. package/dist/output-schema.js.map +1 -0
  122. package/dist/tui/AgentExplorer.d.ts +13 -2
  123. package/dist/tui/AgentExplorer.d.ts.map +1 -1
  124. package/dist/tui/AgentExplorer.js +85 -23
  125. package/dist/tui/AgentExplorer.js.map +1 -1
  126. package/dist/tui/App.d.ts.map +1 -1
  127. package/dist/tui/App.js +694 -150
  128. package/dist/tui/App.js.map +1 -1
  129. package/dist/tui/BrandHeader.d.ts +1 -4
  130. package/dist/tui/BrandHeader.d.ts.map +1 -1
  131. package/dist/tui/BrandHeader.js +4 -8
  132. package/dist/tui/BrandHeader.js.map +1 -1
  133. package/dist/tui/Composer.d.ts +2 -1
  134. package/dist/tui/Composer.d.ts.map +1 -1
  135. package/dist/tui/Composer.js +26 -3
  136. package/dist/tui/Composer.js.map +1 -1
  137. package/dist/tui/PermissionOverlay.d.ts +5 -2
  138. package/dist/tui/PermissionOverlay.d.ts.map +1 -1
  139. package/dist/tui/PermissionOverlay.js +14 -6
  140. package/dist/tui/PermissionOverlay.js.map +1 -1
  141. package/dist/tui/Picker.d.ts +2 -1
  142. package/dist/tui/Picker.d.ts.map +1 -1
  143. package/dist/tui/Picker.js +104 -24
  144. package/dist/tui/Picker.js.map +1 -1
  145. package/dist/tui/ProviderSetup.d.ts +6 -0
  146. package/dist/tui/ProviderSetup.d.ts.map +1 -0
  147. package/dist/tui/ProviderSetup.js +125 -0
  148. package/dist/tui/ProviderSetup.js.map +1 -0
  149. package/dist/tui/ResumePicker.d.ts.map +1 -1
  150. package/dist/tui/ResumePicker.js +5 -3
  151. package/dist/tui/ResumePicker.js.map +1 -1
  152. package/dist/tui/StatusPanel.d.ts +5 -0
  153. package/dist/tui/StatusPanel.d.ts.map +1 -0
  154. package/dist/tui/StatusPanel.js +11 -0
  155. package/dist/tui/StatusPanel.js.map +1 -0
  156. package/dist/tui/TextPrompt.d.ts +3 -1
  157. package/dist/tui/TextPrompt.d.ts.map +1 -1
  158. package/dist/tui/TextPrompt.js +55 -9
  159. package/dist/tui/TextPrompt.js.map +1 -1
  160. package/dist/tui/ToolOutputViewer.d.ts +11 -0
  161. package/dist/tui/ToolOutputViewer.d.ts.map +1 -0
  162. package/dist/tui/ToolOutputViewer.js +39 -0
  163. package/dist/tui/ToolOutputViewer.js.map +1 -0
  164. package/dist/tui/Transcript.d.ts.map +1 -1
  165. package/dist/tui/Transcript.js +10 -4
  166. package/dist/tui/Transcript.js.map +1 -1
  167. package/dist/tui/agent.d.ts +24 -3
  168. package/dist/tui/agent.d.ts.map +1 -1
  169. package/dist/tui/agent.js +362 -97
  170. package/dist/tui/agent.js.map +1 -1
  171. package/dist/tui/live-window.d.ts.map +1 -1
  172. package/dist/tui/live-window.js +5 -1
  173. package/dist/tui/live-window.js.map +1 -1
  174. package/dist/tui/logo.d.ts +4 -4
  175. package/dist/tui/logo.d.ts.map +1 -1
  176. package/dist/tui/logo.js +4 -4
  177. package/dist/tui/logo.js.map +1 -1
  178. package/dist/tui/model-catalogue-view.d.ts +3 -0
  179. package/dist/tui/model-catalogue-view.d.ts.map +1 -0
  180. package/dist/tui/model-catalogue-view.js +50 -0
  181. package/dist/tui/model-catalogue-view.js.map +1 -0
  182. package/dist/tui/model-choices.d.ts +3 -1
  183. package/dist/tui/model-choices.d.ts.map +1 -1
  184. package/dist/tui/model-choices.js +12 -1
  185. package/dist/tui/model-choices.js.map +1 -1
  186. package/dist/tui/model-search.d.ts +4 -0
  187. package/dist/tui/model-search.d.ts.map +1 -0
  188. package/dist/tui/model-search.js +11 -0
  189. package/dist/tui/model-search.js.map +1 -0
  190. package/dist/tui/model-selection-intent.d.ts +8 -0
  191. package/dist/tui/model-selection-intent.d.ts.map +1 -0
  192. package/dist/tui/model-selection-intent.js +96 -0
  193. package/dist/tui/model-selection-intent.js.map +1 -0
  194. package/dist/tui/model-switch-tool.d.ts +7 -0
  195. package/dist/tui/model-switch-tool.d.ts.map +1 -0
  196. package/dist/tui/model-switch-tool.js +74 -0
  197. package/dist/tui/model-switch-tool.js.map +1 -0
  198. package/dist/tui/model-switch.d.ts +35 -0
  199. package/dist/tui/model-switch.d.ts.map +1 -0
  200. package/dist/tui/model-switch.js +106 -0
  201. package/dist/tui/model-switch.js.map +1 -0
  202. package/dist/tui/permission-review.d.ts +2 -0
  203. package/dist/tui/permission-review.d.ts.map +1 -1
  204. package/dist/tui/permission-review.js +82 -15
  205. package/dist/tui/permission-review.js.map +1 -1
  206. package/dist/tui/run-interruption.d.ts +7 -0
  207. package/dist/tui/run-interruption.d.ts.map +1 -1
  208. package/dist/tui/run-interruption.js +41 -0
  209. package/dist/tui/run-interruption.js.map +1 -1
  210. package/dist/tui/slashCommands.d.ts +7 -0
  211. package/dist/tui/slashCommands.d.ts.map +1 -1
  212. package/dist/tui/slashCommands.js +77 -2
  213. package/dist/tui/slashCommands.js.map +1 -1
  214. package/dist/tui/status-card.d.ts +3 -0
  215. package/dist/tui/status-card.d.ts.map +1 -0
  216. package/dist/tui/status-card.js +30 -0
  217. package/dist/tui/status-card.js.map +1 -0
  218. package/dist/tui/status-panel-layout.d.ts +11 -0
  219. package/dist/tui/status-panel-layout.d.ts.map +1 -0
  220. package/dist/tui/status-panel-layout.js +42 -0
  221. package/dist/tui/status-panel-layout.js.map +1 -0
  222. package/dist/tui/types.d.ts +7 -1
  223. package/dist/tui/types.d.ts.map +1 -1
  224. package/package.json +9 -7
@@ -29,7 +29,18 @@
29
29
  * @param currentModel The model in force now, if any — so re-opening the picker
30
30
  * starts on what is already selected rather than resetting to the default.
31
31
  */
32
- export function modelStep(defaultModel, listing, currentModel) {
32
+ export function modelStep(defaultModel, suppliedListing, suppliedCurrentModel, options = {}) {
33
+ // A saved pin does not grant access. In particular, losing a Zen account
34
+ // credential must not put a paid model back into its public-only list.
35
+ const currentModel = suppliedCurrentModel && options.allowModel?.(suppliedCurrentModel) === false
36
+ ? undefined
37
+ : suppliedCurrentModel;
38
+ const listing = suppliedListing.kind === 'ok' && options.allowModel
39
+ ? {
40
+ ...suppliedListing,
41
+ models: suppliedListing.models.filter((model) => options.allowModel?.(model.id)),
42
+ }
43
+ : suppliedListing;
33
44
  const fallback = (notice) => {
34
45
  const choices = [
35
46
  { id: defaultModel, label: defaultModel, note: '(namzu default)' },
@@ -1 +1 @@
1
- {"version":3,"file":"model-choices.js","sourceRoot":"","sources":["../../src/tui/model-choices.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"model-choices.js","sourceRoot":"","sources":["../../src/tui/model-choices.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { ModelChoice } from './model-choices.js';
2
+ /** Match every word against IDs and names, retaining catalogue order and identity. */
3
+ export declare function filterModelChoices(choices: readonly ModelChoice[], query: string): readonly ModelChoice[];
4
+ //# sourceMappingURL=model-search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-search.d.ts","sourceRoot":"","sources":["../../src/tui/model-search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAErD,sFAAsF;AACtF,wBAAgB,kBAAkB,CACjC,OAAO,EAAE,SAAS,WAAW,EAAE,EAC/B,KAAK,EAAE,MAAM,GACX,SAAS,WAAW,EAAE,CAOxB"}
@@ -0,0 +1,11 @@
1
+ /** Match every word against IDs and names, retaining catalogue order and identity. */
2
+ export function filterModelChoices(choices, query) {
3
+ const words = query.normalize('NFKC').toLowerCase().trim().split(/\s+/).filter(Boolean);
4
+ if (words.length === 0)
5
+ return choices;
6
+ return choices.filter((choice) => {
7
+ const text = `${choice.id} ${choice.label}`.normalize('NFKC').toLowerCase();
8
+ return words.every((word) => text.includes(word));
9
+ });
10
+ }
11
+ //# sourceMappingURL=model-search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-search.js","sourceRoot":"","sources":["../../src/tui/model-search.ts"],"names":[],"mappings":"AAEA,sFAAsF;AACtF,MAAM,UAAU,kBAAkB,CACjC,OAA+B,EAC/B,KAAa;IAEb,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IACvF,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,OAAO,CAAA;IACtC,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE;QAChC,MAAM,IAAI,GAAG,GAAG,MAAM,CAAC,EAAE,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAA;QAC3E,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAA;IAClD,CAAC,CAAC,CAAA;AACH,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { ModelSwitchResolution, ModelSwitchResolverOptions } from './model-switch.js';
2
+ /** Only standalone operator selection requests; prose about other work stays model input. */
3
+ export declare function parseModelSelectionIntent(text: string): {
4
+ query: string;
5
+ } | undefined;
6
+ /** Exact IDs first, then a unique complete suffix; never infer a model family or effort. */
7
+ export declare function resolveModelSelectionIntent(query: string, options: ModelSwitchResolverOptions): Promise<ModelSwitchResolution>;
8
+ //# sourceMappingURL=model-selection-intent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-selection-intent.d.ts","sourceRoot":"","sources":["../../src/tui/model-selection-intent.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAA;AAoB1F,6FAA6F;AAC7F,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAQrF;AAQD,4FAA4F;AAC5F,wBAAsB,2BAA2B,CAChD,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,0BAA0B,GACjC,OAAO,CAAC,qBAAqB,CAAC,CAiFhC"}
@@ -0,0 +1,96 @@
1
+ import { canSelectModel } from '../integrations/providers/access.js';
2
+ const ID = '([a-zA-Z0-9][a-zA-Z0-9._:/-]{0,255})';
3
+ const patterns = [
4
+ /^([a-z0-9][a-z0-9._:/ -]{0,255}(?:['’](?:ya|ye|a|e))?)\s+(?:geç|gec|geçer misin|gecer misin|geçebilir misin|gecebilir misin)[.!?]?$/i,
5
+ new RegExp(`^/model\\s+${ID}$`, 'i'),
6
+ new RegExp(`^(?:please\\s+)?(?:switch|change|set)\\s+(?:the\\s+)?model\\s+to\\s+${ID}(?:\\s+please)?[.!?]?$`, 'i'),
7
+ new RegExp(`^(?:can|could)\\s+you\\s+(?:switch|change|set)\\s+(?:the\\s+)?model\\s+to\\s+${ID}(?:\\s+please)?[.!?]?$`, 'i'),
8
+ new RegExp(`^(?:lütfen\\s+)?modeli\\s+${ID}\\s+(?:yap|yapar mısın|yapar misin|yapabilir misin|olarak değiştir|olarak degistir)[.!?]?$`, 'i'),
9
+ ];
10
+ /** Only standalone operator selection requests; prose about other work stays model input. */
11
+ export function parseModelSelectionIntent(text) {
12
+ const trimmed = text.trim();
13
+ if (trimmed.includes('\n'))
14
+ return undefined;
15
+ for (const pattern of patterns) {
16
+ const query = pattern.exec(trimmed)?.[1];
17
+ if (query)
18
+ return { query };
19
+ }
20
+ return undefined;
21
+ }
22
+ const normalized = (id) => id
23
+ .trim()
24
+ .toLowerCase()
25
+ .replace(/[_\s]+/g, '-');
26
+ /** Exact IDs first, then a unique complete suffix; never infer a model family or effort. */
27
+ export async function resolveModelSelectionIntent(query, options) {
28
+ const selectedProvider = options.detected.find(({ entry }) => query.toLowerCase().startsWith(`${entry.id}/`))?.entry.id;
29
+ const modelQuery = selectedProvider ? query.slice(selectedProvider.length + 1) : query;
30
+ const candidates = [];
31
+ let unavailable = false;
32
+ const seen = new Set();
33
+ await Promise.all(options.detected.map(async (detected) => {
34
+ if (!detected.entry.constructible ||
35
+ seen.has(detected.entry.id) ||
36
+ (selectedProvider && detected.entry.id !== selectedProvider))
37
+ return;
38
+ seen.add(detected.entry.id);
39
+ options.signal?.throwIfAborted();
40
+ try {
41
+ const listing = await options.describeModels(detected.entry.id, detected, options.signal);
42
+ if (listing.kind !== 'ok') {
43
+ unavailable = true;
44
+ return;
45
+ }
46
+ for (const item of listing.models) {
47
+ if (canSelectModel(detected.entry, detected.apiKey, item.id))
48
+ candidates.push({ provider: detected.entry.id, model: item.id });
49
+ }
50
+ }
51
+ catch {
52
+ options.signal?.throwIfAborted();
53
+ unavailable = true;
54
+ }
55
+ }));
56
+ options.signal?.throwIfAborted();
57
+ const needle = normalized(modelQuery);
58
+ let exact = candidates.filter((item) => normalized(item.model) === needle);
59
+ let matches = exact.length > 0
60
+ ? exact
61
+ : candidates.filter((item) => /\d/.test(needle) && normalized(item.model).endsWith(`-${needle}`));
62
+ // Turkish dative endings are a fallback, never edits to an already listed ID.
63
+ if (matches.length === 0) {
64
+ const stems = new Set();
65
+ for (const ending of ['ya', 'ye', 'a', 'e']) {
66
+ if (needle.endsWith(ending))
67
+ stems.add(needle.slice(0, -ending.length).replace(/['’]$/, ''));
68
+ }
69
+ exact = candidates.filter((item) => stems.has(normalized(item.model)));
70
+ matches =
71
+ exact.length > 0
72
+ ? exact
73
+ : candidates.filter((item) => [...stems].some((stem) => /\d/.test(stem) && normalized(item.model).endsWith(`-${stem}`)));
74
+ }
75
+ const currentExact = exact.filter((item) => item.provider === options.currentProvider);
76
+ if (currentExact.length === 1)
77
+ matches = currentExact;
78
+ const unique = [
79
+ ...new Map(matches.map((item) => [`${item.provider}:${item.model}`, item])).values(),
80
+ ];
81
+ if (unique.length === 1 && (!unavailable || exact.length > 0)) {
82
+ const match = unique[0];
83
+ if (match)
84
+ return { kind: 'resolved', selection: { id: match.provider, model: match.model } };
85
+ }
86
+ return {
87
+ kind: 'rejected',
88
+ reason: unique.length > 1
89
+ ? `Model "${query}" is ambiguous. Use /model to choose a provider and exact model.`
90
+ : unavailable
91
+ ? `Could not verify all available model catalogues for "${query}". Use /model to choose explicitly.`
92
+ : `Model "${query}" was not found in authenticated model catalogues. Use /model to choose an available model.`,
93
+ ...(unique.length > 0 ? { choices: unique.slice(0, 8) } : {}),
94
+ };
95
+ }
96
+ //# sourceMappingURL=model-selection-intent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-selection-intent.js","sourceRoot":"","sources":["../../src/tui/model-selection-intent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { type ToolContext, type ToolDefinition } from '@namzu/sdk';
2
+ import type { ModelSwitchOutcome, ModelSwitchRequest } from './model-switch.js';
3
+ export type { ModelSwitchOutcome } from './model-switch.js';
4
+ export type RequestModelSwitch = (request: ModelSwitchRequest, context: ToolContext) => Promise<ModelSwitchOutcome>;
5
+ /** Mounted only when the main interactive session supplies this capability. */
6
+ export declare function buildSwitchModelTool(requestSwitch: RequestModelSwitch): ToolDefinition;
7
+ //# sourceMappingURL=model-switch-tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-switch-tool.d.ts","sourceRoot":"","sources":["../../src/tui/model-switch-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,cAAc,EAAkC,MAAM,YAAY,CAAA;AAElG,OAAO,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AAE/E,YAAY,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AAE3D,MAAM,MAAM,kBAAkB,GAAG,CAChC,OAAO,EAAE,kBAAkB,EAC3B,OAAO,EAAE,WAAW,KAChB,OAAO,CAAC,kBAAkB,CAAC,CAAA;AAEhC,+EAA+E;AAC/E,wBAAgB,oBAAoB,CAAC,aAAa,EAAE,kBAAkB,GAAG,cAAc,CAwEtF"}
@@ -0,0 +1,74 @@
1
+ import { defineTool, mcpJsonSchemaToZod } from '@namzu/sdk';
2
+ /** Mounted only when the main interactive session supplies this capability. */
3
+ export function buildSwitchModelTool(requestSwitch) {
4
+ return defineTool({
5
+ name: 'switch_model',
6
+ description: 'Change the current conversation model when the user requests it. Call this tool directly and alone, after any other work is finished; no tool search is needed. Supply the full model ID including its variant (for example gpt-5.6-luna, not just gpt-5.6), and optionally a provider ID. This tool checks available model catalogues and returns relevant choices on failure. Acceptance ends the turn automatically; the host applies the session-only change and confirms it. Do not repeat an accepted request or use this tool to change a delegated agent.',
7
+ inputSchema: mcpJsonSchemaToZod({
8
+ type: 'object',
9
+ properties: {
10
+ model: {
11
+ type: 'string',
12
+ minLength: 1,
13
+ maxLength: 256,
14
+ description: 'Exact model ID from a detected provider catalogue.',
15
+ },
16
+ provider: {
17
+ type: 'string',
18
+ minLength: 1,
19
+ maxLength: 128,
20
+ description: 'Optional exact provider ID. Omit to prefer the current provider when it lists this model.',
21
+ },
22
+ },
23
+ required: ['model'],
24
+ additionalProperties: false,
25
+ }),
26
+ category: 'custom',
27
+ permissions: [],
28
+ // This only requests a host-controlled session setting change after an
29
+ // explicit user request. It performs no workspace or external write.
30
+ readOnly: true,
31
+ destructive: false,
32
+ concurrencySafe: false,
33
+ terminal: true,
34
+ presentCall: (input) => ({
35
+ kind: 'generic',
36
+ label: `${input.provider ? `${input.provider}/` : ''}${input.model}`,
37
+ }),
38
+ presentResult: (_input, result) => result.success ? { kind: 'generic', label: result.output, visibility: 'hidden' } : undefined,
39
+ timeoutMs: 10_000,
40
+ async execute(input, context) {
41
+ context.abortSignal?.throwIfAborted();
42
+ let outcome;
43
+ try {
44
+ outcome = await requestSwitch(input, context);
45
+ }
46
+ catch {
47
+ context.abortSignal?.throwIfAborted();
48
+ return {
49
+ success: false,
50
+ output: '',
51
+ error: 'Could not queue the model change. The active model has not changed.',
52
+ };
53
+ }
54
+ context.abortSignal?.throwIfAborted();
55
+ if (outcome.kind === 'rejected') {
56
+ const choices = outcome.choices
57
+ ?.map((choice) => `${choice.provider}: ${choice.model}`)
58
+ .join('; ');
59
+ return {
60
+ success: false,
61
+ output: '',
62
+ error: `${outcome.reason}${choices ? ` Available choices: ${choices}.` : ''}`,
63
+ ...(outcome.choices ? { data: { choices: outcome.choices } } : {}),
64
+ };
65
+ }
66
+ return {
67
+ success: true,
68
+ output: `Model change queued: ${outcome.selection.id}/${outcome.selection.model}. Pending host application for this session.`,
69
+ data: { status: 'pending', provider: outcome.selection.id, model: outcome.selection.model },
70
+ };
71
+ },
72
+ });
73
+ }
74
+ //# sourceMappingURL=model-switch-tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-switch-tool.js","sourceRoot":"","sources":["../../src/tui/model-switch-tool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import type { DetectedProvider, ProviderChoice, ProviderId } from '../integrations/providers/index.js';
2
+ import type { ModelListing } from './agent.js';
3
+ export interface ModelSwitchRequest {
4
+ readonly model: string;
5
+ readonly provider?: string;
6
+ }
7
+ export type ModelSwitchSelection = ProviderChoice & {
8
+ readonly model: string;
9
+ };
10
+ export interface ModelSwitchRejection {
11
+ readonly kind: 'rejected';
12
+ readonly reason: string;
13
+ readonly choices?: readonly {
14
+ readonly provider: ProviderId;
15
+ readonly model: string;
16
+ }[];
17
+ }
18
+ export type ModelSwitchResolution = {
19
+ readonly kind: 'resolved';
20
+ readonly selection: ModelSwitchSelection;
21
+ } | ModelSwitchRejection;
22
+ /** Acceptance schedules a change; only the interactive host can commit it. */
23
+ export type ModelSwitchOutcome = {
24
+ readonly kind: 'pending';
25
+ readonly selection: ModelSwitchSelection;
26
+ } | ModelSwitchRejection;
27
+ export interface ModelSwitchResolverOptions {
28
+ readonly currentProvider: ProviderId;
29
+ readonly detected: readonly DetectedProvider[];
30
+ readonly describeModels: (id: ProviderId, detected: DetectedProvider, signal?: AbortSignal) => Promise<ModelListing>;
31
+ readonly signal?: AbortSignal;
32
+ }
33
+ /** Resolve exact catalogue IDs without inferring a provider from the model's name. */
34
+ export declare function resolveModelSwitch(request: ModelSwitchRequest, options: ModelSwitchResolverOptions): Promise<ModelSwitchResolution>;
35
+ //# sourceMappingURL=model-switch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-switch.d.ts","sourceRoot":"","sources":["../../src/tui/model-switch.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACX,gBAAgB,EAChB,cAAc,EACd,UAAU,EACV,MAAM,oCAAoC,CAAA;AAC3C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAE9C,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAC1B;AAED,MAAM,MAAM,oBAAoB,GAAG,cAAc,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAA;AAE9E,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS;QAAE,QAAQ,CAAC,QAAQ,EAAE,UAAU,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CACvF;AAED,MAAM,MAAM,qBAAqB,GAC9B;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,oBAAoB,CAAA;CAAE,GACvE,oBAAoB,CAAA;AAEvB,8EAA8E;AAC9E,MAAM,MAAM,kBAAkB,GAC3B;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,oBAAoB,CAAA;CAAE,GACtE,oBAAoB,CAAA;AAEvB,MAAM,WAAW,0BAA0B;IAC1C,QAAQ,CAAC,eAAe,EAAE,UAAU,CAAA;IACpC,QAAQ,CAAC,QAAQ,EAAE,SAAS,gBAAgB,EAAE,CAAA;IAC9C,QAAQ,CAAC,cAAc,EAAE,CACxB,EAAE,EAAE,UAAU,EACd,QAAQ,EAAE,gBAAgB,EAC1B,MAAM,CAAC,EAAE,WAAW,KAChB,OAAO,CAAC,YAAY,CAAC,CAAA;IAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAC7B;AAED,sFAAsF;AACtF,wBAAsB,kBAAkB,CACvC,OAAO,EAAE,kBAAkB,EAC3B,OAAO,EAAE,0BAA0B,GACjC,OAAO,CAAC,qBAAqB,CAAC,CAqGhC"}
@@ -0,0 +1,106 @@
1
+ import { canSelectModel } from '../integrations/providers/access.js';
2
+ /** Resolve exact catalogue IDs without inferring a provider from the model's name. */
3
+ export async function resolveModelSwitch(request, options) {
4
+ const { signal } = options;
5
+ signal?.throwIfAborted();
6
+ const model = request.model.trim();
7
+ const providerId = request.provider?.trim();
8
+ if (!model || model.length > 256 || (providerId !== undefined && !providerId)) {
9
+ return { kind: 'rejected', reason: 'Supply an exact model ID and, optionally, a provider ID.' };
10
+ }
11
+ const seen = new Set();
12
+ const usable = options.detected.filter((detected) => {
13
+ const { entry } = detected;
14
+ if (!entry.constructible || seen.has(entry.id))
15
+ return false;
16
+ seen.add(entry.id);
17
+ return true;
18
+ });
19
+ const selected = providerId ? usable.find(({ entry }) => entry.id === providerId) : undefined;
20
+ if (providerId && !selected) {
21
+ return {
22
+ kind: 'rejected',
23
+ reason: `Provider "${providerId}" is unavailable in this session. Available providers: ${usable.map(({ entry }) => entry.id).join(', ') || 'none'}.`,
24
+ };
25
+ }
26
+ if (selected && !canSelectModel(selected.entry, selected.apiKey, model)) {
27
+ return {
28
+ kind: 'rejected',
29
+ reason: `Model "${model}" requires a credential for provider "${selected.entry.id}".`,
30
+ };
31
+ }
32
+ const listed = new Map();
33
+ const inspect = async (detected) => {
34
+ signal?.throwIfAborted();
35
+ if (!canSelectModel(detected.entry, detected.apiKey, model))
36
+ return false;
37
+ let listing;
38
+ try {
39
+ listing = await options.describeModels(detected.entry.id, detected, signal);
40
+ }
41
+ catch {
42
+ signal?.throwIfAborted();
43
+ // Provider failures can contain credentials or private endpoint details.
44
+ listing = { kind: 'failed', reason: 'Model listing failed.' };
45
+ }
46
+ signal?.throwIfAborted();
47
+ listed.set(detected.entry.id, listing);
48
+ return listing.kind === 'ok' && listing.models.some((candidate) => candidate.id === model);
49
+ };
50
+ const resolve = (detected) => ({
51
+ kind: 'resolved',
52
+ selection: { id: detected.entry.id, model },
53
+ });
54
+ const first = selected ?? usable.find(({ entry }) => entry.id === options.currentProvider);
55
+ if (first && (await inspect(first)))
56
+ return resolve(first);
57
+ const candidates = selected ? [selected] : usable;
58
+ const matches = selected
59
+ ? []
60
+ : (await Promise.all(candidates
61
+ .filter((candidate) => candidate !== first)
62
+ .map(async (candidate) => ((await inspect(candidate)) ? candidate : undefined)))).filter((candidate) => candidate !== undefined);
63
+ signal?.throwIfAborted();
64
+ const uniqueMatch = matches.length === 1 ? matches[0] : undefined;
65
+ if (uniqueMatch)
66
+ return resolve(uniqueMatch);
67
+ if (matches.length > 1) {
68
+ return {
69
+ kind: 'rejected',
70
+ reason: `Model "${model}" is available from multiple providers. Specify one: ${matches.map(({ entry }) => entry.id).join(', ')}.`,
71
+ choices: matches.map(({ entry }) => ({ provider: entry.id, model })),
72
+ };
73
+ }
74
+ const choices = candidates.flatMap((candidate) => {
75
+ const listing = listed.get(candidate.entry.id);
76
+ return listing?.kind === 'ok'
77
+ ? listing.models
78
+ .filter((item) => canSelectModel(candidate.entry, candidate.apiKey, item.id))
79
+ .map((item) => ({ provider: candidate.entry.id, model: item.id }))
80
+ : [];
81
+ });
82
+ const unverified = candidates
83
+ .filter((candidate) => {
84
+ const listing = listed.get(candidate.entry.id);
85
+ return listing && listing.kind !== 'ok';
86
+ })
87
+ .map(({ entry }) => entry.id);
88
+ // Suggest close catalogue IDs first, before bounding the receipt. A large
89
+ // unrelated provider catalogue must not crowd the requested family out.
90
+ // Ranking is recovery guidance only; partial IDs never select a model.
91
+ const terms = model.toLowerCase().match(/[a-z]+|\d+(?:\.\d+)*/g) ?? [];
92
+ const rankedChoices = choices
93
+ .map((choice) => {
94
+ const candidateTerms = new Set(choice.model.toLowerCase().match(/[a-z]+|\d+(?:\.\d+)*/g));
95
+ return { choice, score: terms.filter((term) => candidateTerms.has(term)).length };
96
+ })
97
+ .sort((a, b) => b.score - a.score)
98
+ .slice(0, 8)
99
+ .map(({ choice }) => choice);
100
+ return {
101
+ kind: 'rejected',
102
+ reason: `Model "${model}" was not found in the available model catalogues.${unverified.length > 0 ? ` Could not verify the catalogue for: ${unverified.join(', ')}.` : ''} Use an exact listed model ID.`,
103
+ ...(rankedChoices.length > 0 ? { choices: rankedChoices } : {}),
104
+ };
105
+ }
106
+ //# sourceMappingURL=model-switch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-switch.js","sourceRoot":"","sources":["../../src/tui/model-switch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAA;AAyCpE,sFAAsF;AACtF,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACvC,OAA2B,EAC3B,OAAmC;IAEnC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAA;IAC1B,MAAM,EAAE,cAAc,EAAE,CAAA;IACxB,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAA;IAClC,MAAM,UAAU,GAAG,OAAO,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAA;IAC3C,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,KAAK,SAAS,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/E,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,0DAA0D,EAAE,CAAA;IAChG,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAc,CAAA;IAClC,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE;QACnD,MAAM,EAAE,KAAK,EAAE,GAAG,QAAQ,CAAA;QAC1B,IAAI,CAAC,KAAK,CAAC,aAAa,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YAAE,OAAO,KAAK,CAAA;QAC5D,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;QAClB,OAAO,IAAI,CAAA;IACZ,CAAC,CAAC,CAAA;IACF,MAAM,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IAC7F,IAAI,UAAU,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC7B,OAAO;YACN,IAAI,EAAE,UAAU;YAChB,MAAM,EAAE,aAAa,UAAU,0DAA0D,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,MAAM,GAAG;SACpJ,CAAA;IACF,CAAC;IACD,IAAI,QAAQ,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC;QACzE,OAAO;YACN,IAAI,EAAE,UAAU;YAChB,MAAM,EAAE,UAAU,KAAK,yCAAyC,QAAQ,CAAC,KAAK,CAAC,EAAE,IAAI;SACrF,CAAA;IACF,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,GAAG,EAA4B,CAAA;IAClD,MAAM,OAAO,GAAG,KAAK,EAAE,QAA0B,EAAoB,EAAE;QACtE,MAAM,EAAE,cAAc,EAAE,CAAA;QACxB,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC;YAAE,OAAO,KAAK,CAAA;QACzE,IAAI,OAAqB,CAAA;QACzB,IAAI,CAAC;YACJ,OAAO,GAAG,MAAM,OAAO,CAAC,cAAc,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAA;QAC5E,CAAC;QAAC,MAAM,CAAC;YACR,MAAM,EAAE,cAAc,EAAE,CAAA;YACxB,yEAAyE;YACzE,OAAO,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,uBAAuB,EAAE,CAAA;QAC9D,CAAC;QACD,MAAM,EAAE,cAAc,EAAE,CAAA;QACxB,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;QACtC,OAAO,OAAO,CAAC,IAAI,KAAK,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,KAAK,CAAC,CAAA;IAC3F,CAAC,CAAA;IACD,MAAM,OAAO,GAAG,CAAC,QAA0B,EAAyB,EAAE,CAAC,CAAC;QACvE,IAAI,EAAE,UAAU;QAChB,SAAS,EAAE,EAAE,EAAE,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE;KAC3C,CAAC,CAAA;IACF,MAAM,KAAK,GAAG,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,OAAO,CAAC,eAAe,CAAC,CAAA;IAC1F,IAAI,KAAK,IAAI,CAAC,MAAM,OAAO,CAAC,KAAK,CAAC,CAAC;QAAE,OAAO,OAAO,CAAC,KAAK,CAAC,CAAA;IAC1D,MAAM,UAAU,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAA;IACjD,MAAM,OAAO,GAAG,QAAQ;QACvB,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,CACA,MAAM,OAAO,CAAC,GAAG,CAChB,UAAU;aACR,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,KAAK,KAAK,CAAC;aAC1C,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAChF,CACD,CAAC,MAAM,CAAC,CAAC,SAAS,EAAiC,EAAE,CAAC,SAAS,KAAK,SAAS,CAAC,CAAA;IACjF,MAAM,EAAE,cAAc,EAAE,CAAA;IACxB,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IACjE,IAAI,WAAW;QAAE,OAAO,OAAO,CAAC,WAAW,CAAC,CAAA;IAC5C,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,OAAO;YACN,IAAI,EAAE,UAAU;YAChB,MAAM,EAAE,UAAU,KAAK,wDAAwD,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;YACjI,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;SACpE,CAAA;IACF,CAAC;IACD,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE;QAChD,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;QAC9C,OAAO,OAAO,EAAE,IAAI,KAAK,IAAI;YAC5B,CAAC,CAAC,OAAO,CAAC,MAAM;iBACb,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,cAAc,CAAC,SAAS,CAAC,KAAK,EAAE,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;iBAC5E,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;YACpE,CAAC,CAAC,EAAE,CAAA;IACN,CAAC,CAAC,CAAA;IACF,MAAM,UAAU,GAAG,UAAU;SAC3B,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE;QACrB,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;QAC9C,OAAO,OAAO,IAAI,OAAO,CAAC,IAAI,KAAK,IAAI,CAAA;IACxC,CAAC,CAAC;SACD,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;IAC9B,0EAA0E;IAC1E,wEAAwE;IACxE,uEAAuE;IACvE,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,uBAAuB,CAAC,IAAI,EAAE,CAAA;IACtE,MAAM,aAAa,GAAG,OAAO;SAC3B,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;QACf,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC,CAAA;QACzF,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,CAAA;IAClF,CAAC,CAAC;SACD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;SACjC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;SACX,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,CAAA;IAC7B,OAAO;QACN,IAAI,EAAE,UAAU;QAChB,MAAM,EAAE,UAAU,KAAK,qDAAqD,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,wCAAwC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,gCAAgC;QACzM,GAAG,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC/D,CAAA;AACF,CAAC"}
@@ -30,6 +30,8 @@ export type PermissionReviewResult = {
30
30
  readonly reason: 'too_large' | 'unrepresentable';
31
31
  };
32
32
  export interface PermissionReviewSummary {
33
+ /** Compact agent plan; full prepared arguments remain available in the exact view. */
34
+ readonly compactText?: string;
33
35
  /** Complete, terminal-safe source for the readable pager. */
34
36
  readonly text: string;
35
37
  /** True only when the formatter knows every executable input field. */
@@ -1 +1 @@
1
- {"version":3,"file":"permission-review.d.ts","sourceRoot":"","sources":["../../src/tui/permission-review.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,eAAO,MAAM,2BAA2B,OAAQ,CAAA;AAEhD,qEAAqE;AACrE,eAAO,MAAM,2BAA2B,IAAI,CAAA;AAE5C;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAGjF;AAED,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;IACvB,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAA;CAC/B;AAED,MAAM,MAAM,sBAAsB,GAC/B;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACpE;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,iBAAiB,CAAA;CAAE,CAAA;AAE3E,MAAM,WAAW,uBAAuB;IACvC,6DAA6D;IAC7D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,uEAAuE;IACvE,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;CAC1B;AASD,6EAA6E;AAC7E,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,WAAW,GAAG,iBAAiB,GAAG,MAAM,CAIvF;AAED,uEAAuE;AACvE,MAAM,WAAW,mBAAmB;IACnC,wDAAwD;IACxD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,8DAA8D;IAC9D,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAA;CAC9B;AAKD;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACpC,KAAK,EAAE,SAAS,oBAAoB,EAAE,EACtC,QAAQ,SAA8B,GACpC,sBAAsB,CAqJxB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,uBAAuB,CA6D9E;AAmRD;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CACnC,MAAM,EAAE,MAAM,EACd,eAAe,EAAE,MAAM,GAAG,SAAS,GACjC,SAAS,mBAAmB,EAAE,CA6BhC"}
1
+ {"version":3,"file":"permission-review.d.ts","sourceRoot":"","sources":["../../src/tui/permission-review.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,eAAO,MAAM,2BAA2B,OAAQ,CAAA;AAEhD,qEAAqE;AACrE,eAAO,MAAM,2BAA2B,IAAI,CAAA;AAE5C;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAGjF;AAED,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;IACvB,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAA;CAC/B;AAED,MAAM,MAAM,sBAAsB,GAC/B;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACpE;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,iBAAiB,CAAA;CAAE,CAAA;AAE3E,MAAM,WAAW,uBAAuB;IACvC,sFAAsF;IACtF,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,6DAA6D;IAC7D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,uEAAuE;IACvE,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;CAC1B;AASD,6EAA6E;AAC7E,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,WAAW,GAAG,iBAAiB,GAAG,MAAM,CAIvF;AAED,uEAAuE;AACvE,MAAM,WAAW,mBAAmB;IACnC,wDAAwD;IACxD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,8DAA8D;IAC9D,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAA;CAC9B;AAKD;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACpC,KAAK,EAAE,SAAS,oBAAoB,EAAE,EACtC,QAAQ,SAA8B,GACpC,sBAAsB,CAqJxB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,uBAAuB,CA+E9E;AAgVD;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CACnC,MAAM,EAAE,MAAM,EACd,eAAe,EAAE,MAAM,GAAG,SAAS,GACjC,SAAS,mBAAmB,EAAE,CA6BhC"}
@@ -224,22 +224,34 @@ export function buildPermissionSummary(review) {
224
224
  }
225
225
  const readable = summarizeKnownCall(call.name, call.input);
226
226
  complete &&= readable.complete;
227
- calls.push({ name: call.name, isDestructive: call.isDestructive, readable });
227
+ calls.push({
228
+ name: call.name,
229
+ isDestructive: call.isDestructive,
230
+ readable,
231
+ input: call.input,
232
+ });
228
233
  }
234
+ const compactText = complete &&
235
+ calls.length > 0 &&
236
+ calls.every((call) => call.name === 'Agent' && call.readable.label !== undefined)
237
+ ? compactAgentPlan(calls)
238
+ : undefined;
229
239
  if (complete &&
230
240
  calls.length > 1 &&
231
241
  calls.every((call) => call.name === 'Agent' && call.readable.label !== undefined)) {
232
- const overview = calls.map((call, index) => `${index + 1}. ${call.readable.label}`);
242
+ const overview = calls.map((call, index) => `${index + 1}. ${call.readable.label}${call.isDestructive ? ' · destructive' : ''}`);
233
243
  const details = calls.map((call, index) => [
234
- `${index + 1}. ${call.readable.label}`,
244
+ `${index + 1}. ${call.readable.label}${call.isDestructive ? ' · destructive' : ''}`,
235
245
  ...call.readable.lines.map((line) => ` ${line}`),
236
246
  ].join('\n'));
237
247
  return {
238
248
  text: [...overview, '', 'Task details', '', ...details].join('\n'),
249
+ ...(compactText !== undefined ? { compactText } : {}),
239
250
  complete: true,
240
251
  };
241
252
  }
242
253
  return {
254
+ ...(compactText !== undefined ? { compactText } : {}),
243
255
  text: calls
244
256
  .map((call, index) => [
245
257
  `${index + 1}. ${call.name}${call.isDestructive ? ' · destructive' : ''}`,
@@ -289,11 +301,14 @@ function summarizeKnownCall(name, input) {
289
301
  // exact view has to show, not one this summary may pick a half of.
290
302
  (input.content === undefined) !== (input.newStr === undefined);
291
303
  if (shapeIsKnown) {
292
- const lines = body.split('\n');
304
+ const lines = body === '' ? [] : body.split('\n');
305
+ if (lines.at(-1) === '')
306
+ lines.pop();
293
307
  return {
294
308
  lines: [
295
309
  `${input.path} · write ${lines.length} line${lines.length === 1 ? '' : 's'}`,
296
- ...diffLines('+', lines),
310
+ 'Full replacement body · may overwrite an existing file',
311
+ ...lines.map((line) => ` ${line}`),
297
312
  ],
298
313
  complete: true,
299
314
  };
@@ -304,16 +319,22 @@ function summarizeKnownCall(name, input) {
304
319
  'description',
305
320
  'prompt',
306
321
  'subagent_type',
322
+ 'model',
323
+ 'provider',
324
+ 'effort',
307
325
  'role',
308
326
  'workflow',
309
327
  'phase',
310
328
  'phase_order',
329
+ 'run_in_background',
311
330
  ]);
312
331
  const keys = Object.keys(input);
313
332
  const shapeIsKnown = keys.every((key) => allowed.has(key)) &&
314
333
  typeof input.description === 'string' &&
315
334
  typeof input.prompt === 'string' &&
335
+ (input.run_in_background === undefined || typeof input.run_in_background === 'boolean') &&
316
336
  (input.subagent_type === undefined || typeof input.subagent_type === 'string') &&
337
+ ['model', 'provider', 'effort'].every((key) => input[key] === undefined || typeof input[key] === 'string') &&
317
338
  (input.role === undefined || typeof input.role === 'string') &&
318
339
  (input.workflow === undefined || typeof input.workflow === 'string') &&
319
340
  (input.phase === undefined || typeof input.phase === 'string') &&
@@ -324,21 +345,28 @@ function summarizeKnownCall(name, input) {
324
345
  return {
325
346
  lines: [
326
347
  ...readableField('Task', known.description),
327
- ...(known.subagent_type !== undefined
328
- ? [
329
- `Type: ${known.subagent_type}${known.subagent_type === 'explore' ? ' (read-only)' : ''}`,
330
- ]
348
+ ...readableField('Agent', agentTypeLabel(known.subagent_type)),
349
+ ...(known.model !== undefined ? readableField('Model', known.model) : []),
350
+ ...(known.provider !== undefined ? readableField('Provider', known.provider) : []),
351
+ ...(known.effort !== undefined ? readableField('Effort', known.effort) : []),
352
+ ...(known.run_in_background !== undefined
353
+ ? [`Execution: ${known.run_in_background ? 'background' : 'wait for result'}`]
331
354
  : []),
332
- ...readableField('Instructions', known.prompt),
333
- ...(known.role !== undefined ? readableField('Specialist', known.role) : []),
334
- ...(known.workflow !== undefined ? readableField('Workflow', known.workflow) : []),
335
- ...(known.phase !== undefined ? readableField('Phase', known.phase) : []),
355
+ ...(known.subagent_type === 'explore'
356
+ ? ['Tools: reading and searching only']
357
+ : known.subagent_type === undefined || known.subagent_type === 'general-purpose'
358
+ ? ['Tools: files and commands, subject to approval rules']
359
+ : []),
360
+ ...(known.role !== undefined ? readableField('Role', known.role) : []),
361
+ ...(known.workflow !== undefined ? readableField('Workflow label', known.workflow) : []),
362
+ ...(known.phase !== undefined ? readableField('Phase label', known.phase) : []),
336
363
  ...(known.phase_order !== undefined
337
- ? [`Phase order: ${String(known.phase_order + 1)}`]
364
+ ? [`Phase display order: ${String(known.phase_order + 1)}`]
338
365
  : []),
366
+ ...readableField('Instructions', known.prompt),
339
367
  ],
340
368
  complete: true,
341
- label: oneLine(known.description),
369
+ label: `${oneLine(known.description)} · ${oneLine(agentTypeLabel(known.subagent_type))}`,
342
370
  };
343
371
  }
344
372
  }
@@ -369,6 +397,45 @@ function summarizeKnownCall(name, input) {
369
397
  const PLAIN_TOOL_NAME = /^[\w.:-]+$/u;
370
398
  /** The tools with a formatter above; an evolved shape of one opens exact-first. */
371
399
  const FORMATTED_TOOLS = new Set(['bash', 'edit', 'write', 'Agent']);
400
+ /** Labels group only the calls in this approval; they never invent execution phases. */
401
+ function compactAgentPlan(calls) {
402
+ const lines = [];
403
+ let previousGroup = '';
404
+ for (const [index, call] of calls.entries()) {
405
+ const input = call.input;
406
+ const workflow = typeof input.workflow === 'string' ? oneLine(input.workflow) : '';
407
+ const phase = typeof input.phase === 'string' ? oneLine(input.phase) : '';
408
+ const group = JSON.stringify([workflow, phase]);
409
+ if (group !== previousGroup) {
410
+ if (workflow || phase)
411
+ lines.push([workflow, phase].filter(Boolean).join(' / '));
412
+ else if (previousGroup)
413
+ lines.push('Other agents');
414
+ previousGroup = group;
415
+ }
416
+ const type = input.subagent_type;
417
+ const access = type === 'explore'
418
+ ? 'read-only'
419
+ : type === undefined || type === 'general-purpose'
420
+ ? 'files + commands'
421
+ : String(type);
422
+ const background = input.run_in_background === true ? ' · background' : '';
423
+ const selection = [input.provider, input.model, input.effort]
424
+ .filter((value) => typeof value === 'string')
425
+ .map((value) => oneLine(String(value)))
426
+ .join(' / ');
427
+ const modelLabel = selection ? ` · ${selection}` : '';
428
+ lines.push(`${index === calls.length - 1 ? '└' : '├'}─ [ ${index + 1}. ${oneLine(String(input.description))} · ${access}${modelLabel}${background}${call.isDestructive ? ' · destructive' : ''} ]`);
429
+ }
430
+ return terminalDisplayText(lines.join('\n'));
431
+ }
432
+ function agentTypeLabel(type) {
433
+ if (type === undefined)
434
+ return 'general-purpose (default)';
435
+ if (type === 'explore')
436
+ return 'explore (read-only tools)';
437
+ return type;
438
+ }
372
439
  function oneLine(value) {
373
440
  return value.replace(/\s+/gu, ' ').trim() || '(untitled task)';
374
441
  }