shortcutxl 0.3.76 → 0.3.77

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 (173) hide show
  1. package/BINARY-INVENTORY.json +813 -813
  2. package/CHANGELOG.md +6 -0
  3. package/dist/ai/models.d.ts +10 -6
  4. package/dist/ai/models.generated.d.ts +72 -0
  5. package/dist/ai/models.generated.js +33 -0
  6. package/dist/ai/models.js +36 -13
  7. package/dist/ai/providers/anthropic.d.ts +4 -2
  8. package/dist/ai/providers/anthropic.js +59 -29
  9. package/dist/ai/providers/azure-openai-responses.d.ts +2 -1
  10. package/dist/ai/providers/azure-openai-responses.js +4 -20
  11. package/dist/ai/providers/google-vertex.d.ts +8 -2
  12. package/dist/ai/providers/google-vertex.js +66 -54
  13. package/dist/ai/providers/google.js +15 -48
  14. package/dist/ai/providers/openai-completions.d.ts +4 -1
  15. package/dist/ai/providers/openai-completions.js +26 -10
  16. package/dist/ai/providers/openai-reasoning.d.ts +5 -0
  17. package/dist/ai/providers/openai-reasoning.js +13 -0
  18. package/dist/ai/providers/openai-responses-shared.js +1 -1
  19. package/dist/ai/providers/openai-responses.d.ts +6 -2
  20. package/dist/ai/providers/openai-responses.js +28 -23
  21. package/dist/ai/providers/simple-options.d.ts +2 -3
  22. package/dist/ai/providers/simple-options.js +4 -6
  23. package/dist/ai/types.d.ts +19 -2
  24. package/dist/app/agent-session-runtime-adapter.js +7 -6
  25. package/dist/app/approvals/approval-errors.d.ts +15 -0
  26. package/dist/app/approvals/approval-errors.js +14 -0
  27. package/dist/app/approvals/runtime-approval-gates.d.ts +1 -2
  28. package/dist/app/approvals/tool-approval.d.ts +1 -0
  29. package/dist/app/approvals/tool-approval.js +11 -23
  30. package/dist/app/approvals/types.d.ts +0 -14
  31. package/dist/app/approvals/types.js +0 -2
  32. package/dist/app/background/tool-summaries.js +0 -2
  33. package/dist/app/local/tools/execute-code/executor.d.ts +1 -1
  34. package/dist/app/local/tools/execute-code/executor.js +20 -10
  35. package/dist/app/local/tools/execute-code/tool.js +21 -2
  36. package/dist/app/permissions/runtime-approval-flow.d.ts +1 -5
  37. package/dist/app/permissions/runtime-approval-flow.js +0 -28
  38. package/dist/app/permissions/tool-gates.d.ts +2 -3
  39. package/dist/app/permissions/tool-gates.js +3 -81
  40. package/dist/app/prompts/shared-guidelines.js +2 -2
  41. package/dist/app/providers/google-vertex-gateway.js +4 -51
  42. package/dist/app/providers/model-registry.d.ts +1 -0
  43. package/dist/app/providers/model-registry.js +39 -0
  44. package/dist/app/providers/model-resolver.js +10 -7
  45. package/dist/app/providers/register-shortcut-provider.js +2 -6
  46. package/dist/app/providers/shortcut-api-v2-transport.js +4 -0
  47. package/dist/app/providers/shortcut-llm-proxy-client.d.ts +2 -2
  48. package/dist/app/providers/shortcut-llm-proxy-client.js +1 -0
  49. package/dist/app/resources/package-manager.js +2 -123
  50. package/dist/app/resources/resource-patterns.d.ts +9 -0
  51. package/dist/app/resources/resource-patterns.js +120 -0
  52. package/dist/app/session/forked-agent.d.ts +2 -2
  53. package/dist/app/session/model-manager.js +3 -2
  54. package/dist/app/session/session-lifecycle.js +3 -2
  55. package/dist/app/session/session-models.d.ts +2 -0
  56. package/dist/app/session/session-models.js +14 -6
  57. package/dist/app/settings-manager.d.ts +3 -3
  58. package/dist/app/shared/tools/execute-code/mog.d.ts +3 -1
  59. package/dist/app/shared/tools/execute-code/mog.js +18 -2
  60. package/dist/app/tools/execute-code/index.d.ts +1 -0
  61. package/dist/app/tools/execute-code/index.js +3 -1
  62. package/dist/app/tools/find-ignore-files.d.ts +3 -0
  63. package/dist/app/tools/find-ignore-files.js +33 -0
  64. package/dist/app/tools/find.js +2 -21
  65. package/dist/app/tools/llm-analysis.js +0 -2
  66. package/dist/app/tools/refresh-context.d.ts +1 -1
  67. package/dist/app/tools/session-settings/update-session-settings.js +2 -2
  68. package/dist/app/tools/take-screenshot.js +0 -2
  69. package/dist/app/tools/task/runner.js +1 -2
  70. package/dist/app/tools/task/task.d.ts +1 -3
  71. package/dist/app/tools/task/task.js +20 -40
  72. package/dist/autocomplete/core.d.ts +33 -0
  73. package/dist/autocomplete/core.js +113 -0
  74. package/dist/{tui → autocomplete}/fuzzy.d.ts +0 -1
  75. package/dist/{tui → autocomplete}/fuzzy.js +0 -1
  76. package/dist/{tui/autocomplete.d.ts → autocomplete/index.d.ts} +0 -1
  77. package/dist/{tui/autocomplete.js → autocomplete/index.js} +62 -158
  78. package/dist/cli/args.js +1 -1
  79. package/dist/cli/list-models.js +1 -1
  80. package/dist/cli.js +25535 -28515
  81. package/dist/contracts/agent-session-store.d.ts +1 -1
  82. package/dist/contracts/agent-settings.d.ts +1 -0
  83. package/dist/contracts/agent-settings.js +2 -1
  84. package/dist/contracts/model-call.d.ts +1 -1
  85. package/dist/contracts/model-stream.d.ts +1 -0
  86. package/dist/contracts/model-stream.js +1 -0
  87. package/dist/contracts/wire.d.ts +2 -6
  88. package/dist/core/agent-engine.js +1 -1
  89. package/dist/core/core-types.d.ts +1 -21
  90. package/dist/core/defaults.d.ts +1 -1
  91. package/dist/core/defaults.js +9 -1
  92. package/dist/core/prompts/agent-guidelines.d.ts +4 -5
  93. package/dist/core/prompts/agent-guidelines.js +28 -42
  94. package/dist/core/session-schema.d.ts +1 -1
  95. package/dist/embedded-agent/ai-invoke.js +5 -3
  96. package/dist/embedded-agent/anthropic-messages-transport.d.ts +5 -20
  97. package/dist/embedded-agent/anthropic-messages-transport.js +23 -786
  98. package/dist/embedded-agent/bootstrap.js +2 -2
  99. package/dist/embedded-agent/compose.js +8 -7
  100. package/dist/embedded-agent/gateway-base-url.d.ts +3 -0
  101. package/dist/embedded-agent/gateway-base-url.js +35 -0
  102. package/dist/embedded-agent/google-vertex-transport.d.ts +2 -10
  103. package/dist/embedded-agent/google-vertex-transport.js +20 -117
  104. package/dist/embedded-agent/host-runtime-options.d.ts +0 -8
  105. package/dist/embedded-agent/host-runtime-options.js +10 -2
  106. package/dist/embedded-agent/host-tools/invoke-llm/contract.d.ts +1 -1
  107. package/dist/embedded-agent/host-tools/invoke-llm/contract.js +3 -1
  108. package/dist/embedded-agent/host-tools/sandbox-llm/contract.d.ts +8 -3
  109. package/dist/embedded-agent/host-tools/sandbox-llm/contract.js +12 -8
  110. package/dist/embedded-agent/host-tools/sandbox-llm/index.d.ts +1 -1
  111. package/dist/embedded-agent/host-tools/sandbox-llm/index.js +1 -1
  112. package/dist/embedded-agent/host-tools/take-screenshot/contract.d.ts +0 -2
  113. package/dist/embedded-agent/host-tools/take-screenshot/contract.js +1 -3
  114. package/dist/embedded-agent/host-tools/take-screenshot/index.d.ts +1 -1
  115. package/dist/embedded-agent/host-tools/take-screenshot/index.js +1 -1
  116. package/dist/embedded-agent/host-tools/task/agents/clone.js +1 -2
  117. package/dist/embedded-agent/host-tools/task/contract.js +1 -1
  118. package/dist/embedded-agent/model-selection.d.ts +0 -6
  119. package/dist/embedded-agent/model-selection.js +15 -8
  120. package/dist/embedded-agent/openai-completions-transport.d.ts +2 -10
  121. package/dist/embedded-agent/openai-completions-transport.js +20 -120
  122. package/dist/embedded-agent/openai-responses-transport.d.ts +2 -10
  123. package/dist/embedded-agent/openai-responses-transport.js +15 -170
  124. package/dist/embedded-agent/prompt/build.js +1 -2
  125. package/dist/embedded-agent/provider-native-request.d.ts +24 -0
  126. package/dist/embedded-agent/provider-native-request.js +64 -0
  127. package/dist/embedded-agent/run-stats.d.ts +1 -1
  128. package/dist/embedded-agent/stream.d.ts +3 -9
  129. package/dist/embedded-agent/stream.js +11 -19
  130. package/dist/main.js +2 -13
  131. package/dist/rpc/rpc-approval-gates.js +1 -2
  132. package/dist/shell/approvals/runtime-approval-gates.js +1 -3
  133. package/dist/shell/components/selectors/model-selector.js +2 -1
  134. package/dist/shell/components/selectors/session-selector-search.js +1 -1
  135. package/dist/shell/components/selectors/thinking-selector.js +7 -6
  136. package/dist/shell/index.d.ts +0 -1
  137. package/dist/shell/index.js +0 -1
  138. package/dist/shell/interactive/interactive-mode.js +3 -1
  139. package/dist/shell/theme/runtime.d.ts +1 -1
  140. package/dist/shell/theme/runtime.js +1 -0
  141. package/dist/shortcut-model-catalog.d.ts +7 -2
  142. package/dist/shortcut-model-catalog.js +127 -10
  143. package/dist/tui/components/editor.d.ts +1 -1
  144. package/dist/tui/components/editor.js +1 -1
  145. package/dist/tui/components/settings-list.js +1 -1
  146. package/dist/tui/editor-component.d.ts +1 -1
  147. package/dist/tui/index.d.ts +0 -7
  148. package/dist/tui/index.js +0 -5
  149. package/native-app/main/index.js +3199 -47
  150. package/native-app/main/{photon_rs-SoVDgheu.js → photon_rs-XkYyYTVA.js} +2 -2
  151. package/native-app/package.json +1 -1
  152. package/native-app/preload/index.cjs +2 -0
  153. package/native-app/renderer/assets/{index-OhGE0UY4.css → index-B9UxxO8s.css} +4 -2
  154. package/native-app/renderer/assets/{index-CFc-oZuS.js → index-CtherCML.js} +231 -4
  155. package/native-app/renderer/index.html +2 -2
  156. package/package.json +16 -3
  157. package/skills/add-custom-model/SKILL.md +52 -0
  158. package/user-docs/dist/shortcutxl-docs.pdf +0 -0
  159. package/xll/ShortcutXL.xll +0 -0
  160. package/xll/python/Lib/site-packages/httpx-0.28.1.dist-info/RECORD +1 -1
  161. package/xll/python/Lib/site-packages/idna-3.18.dist-info/RECORD +1 -1
  162. package/xll/python/Lib/site-packages/pip-26.1.2.dist-info/RECORD +3 -3
  163. package/xll/python/Lib/site-packages/pywin32-311.dist-info/RECORD +2 -2
  164. package/xll/python/Scripts/httpx.exe +0 -0
  165. package/xll/python/Scripts/idna.exe +0 -0
  166. package/xll/python/Scripts/pip.exe +0 -0
  167. package/xll/python/Scripts/pip3.13.exe +0 -0
  168. package/xll/python/Scripts/pip3.exe +0 -0
  169. package/xll/python/Scripts/pywin32_postinstall.exe +0 -0
  170. package/xll/python/Scripts/pywin32_testall.exe +0 -0
  171. package/dist/shell/approvals/task-spawn-approval.d.ts +0 -20
  172. package/dist/shell/approvals/task-spawn-approval.js +0 -93
  173. /package/dist/{tui → autocomplete}/skill-autocomplete.js +0 -0
@@ -10,6 +10,7 @@ import { type ApprovalChoice, type ApprovalGate, type ApprovalRequest } from './
10
10
  export declare function withPreApproval<T extends TSchema, D>(tool: ToolDefinition<T>, approval: ApprovalGate<D>, buildRequest: (params: Record<string, unknown>, ctx: ToolExecutionContext | undefined) => ApprovalRequest<D> | Promise<ApprovalRequest<D>>, options?: {
11
11
  alwaysPrompt?: boolean;
12
12
  isContentSafe?: (params: Record<string, unknown>, ctx: ToolExecutionContext | undefined) => boolean | Promise<boolean>;
13
+ isHeadlessApprovalAllowed?: (ctx: ToolExecutionContext | undefined) => boolean;
13
14
  onRequested?: (request: ApprovalRequest<D>) => void;
14
15
  onAccepted?: (request: ApprovalRequest<D>, choice: ApprovalChoice) => void;
15
16
  onRejected?: (request: ApprovalRequest<D>) => void;
@@ -4,6 +4,7 @@
4
4
  * Wraps a ToolDefinition with a user-approval prompt before executing.
5
5
  */
6
6
  import { getApprovalSurface, resolveApprovalExecutionDecision } from '../permissions/approval-surface.js';
7
+ import { APPROVAL_ERROR_CODE, INTERACTIVE_APPROVAL_UNAVAILABLE_MESSAGE, USER_REJECTED_APPROVAL_MESSAGE, createApprovalErrorResult } from './approval-errors.js';
7
8
  import { APPROVAL } from './types.js';
8
9
  /** Map an ApprovalChoice to a default summary message prepended to the tool result. */
9
10
  function defaultApprovalSummary(choice) {
@@ -12,10 +13,6 @@ function defaultApprovalSummary(choice) {
12
13
  return 'User approved this.';
13
14
  case APPROVAL.ACCEPT_ALL:
14
15
  return 'User enabled session auto-approve.';
15
- case APPROVAL.RUN_FOREGROUND:
16
- return 'User approved running this task in the foreground.';
17
- case APPROVAL.RUN_BACKGROUND:
18
- return 'User approved running this task in the background.';
19
16
  case APPROVAL.ALLOW_ONCE:
20
17
  return 'User allowed this once.';
21
18
  case APPROVAL.ALLOW_FILE:
@@ -35,7 +32,7 @@ function prependApprovalSummary(result, summary) {
35
32
  }
36
33
  /** Wrap a tool with a pre-execution approval gate that prompts when policy requires it. */
37
34
  export function withPreApproval(tool, approval, buildRequest, options = {}) {
38
- const { alwaysPrompt, isContentSafe, onRequested, onAccepted, onRejected, isApprovedChoiceAllowed, describeApprovedChoice, applyApprovalContext } = options;
35
+ const { alwaysPrompt, isContentSafe, isHeadlessApprovalAllowed, onRequested, onAccepted, onRejected, isApprovedChoiceAllowed, describeApprovedChoice, applyApprovalContext } = options;
39
36
  return {
40
37
  name: tool.name,
41
38
  label: tool.label,
@@ -44,48 +41,39 @@ export function withPreApproval(tool, approval, buildRequest, options = {}) {
44
41
  isReadOnly: tool.isReadOnly,
45
42
  promptGuidelines: tool.promptGuidelines,
46
43
  async execute(toolCallId, params, signal, onUpdate, ctx) {
44
+ const extCtx = ctx;
47
45
  const safe = alwaysPrompt
48
46
  ? false
49
47
  : ((await isContentSafe?.(params, ctx)) ?? false);
50
- const extCtx = ctx;
51
48
  const request = await buildRequest(params, ctx);
52
49
  const decision = resolveApprovalExecutionDecision({
53
50
  surface: getApprovalSurface(extCtx),
54
51
  isSafe: safe,
55
52
  isAutoApproved: approval.isAutoApproved(),
56
53
  alwaysRequireExplicitApproval: request.alwaysRequireExplicitApproval === true,
57
- allowHeadlessApproval: ctx?.permissionPolicy?.approvals.allowHeadlessApproval ?? false
54
+ allowHeadlessApproval: isHeadlessApprovalAllowed?.(ctx) ??
55
+ ctx?.permissionPolicy?.approvals.allowHeadlessApproval ??
56
+ false
58
57
  });
59
58
  if (decision === 'deny') {
60
- return {
61
- content: [{ type: 'text', text: 'Tool execution rejected by user.' }],
62
- details: undefined
63
- };
59
+ onRejected?.(request);
60
+ return createApprovalErrorResult(APPROVAL_ERROR_CODE.INTERACTIVE_APPROVAL_UNAVAILABLE, INTERACTIVE_APPROVAL_UNAVAILABLE_MESSAGE, request.kind, tool.name);
64
61
  }
65
62
  if (decision === 'prompt') {
66
63
  if (!extCtx) {
67
64
  onRejected?.(request);
68
- return {
69
- content: [{ type: 'text', text: 'Tool execution rejected by user.' }],
70
- details: undefined
71
- };
65
+ return createApprovalErrorResult(APPROVAL_ERROR_CODE.INTERACTIVE_APPROVAL_UNAVAILABLE, INTERACTIVE_APPROVAL_UNAVAILABLE_MESSAGE, request.kind, tool.name);
72
66
  }
73
67
  onRequested?.(request);
74
68
  const choice = await approval.requestApproval(request, extCtx);
75
69
  if (choice === APPROVAL.REJECT || choice === undefined) {
76
70
  onRejected?.(request);
77
- return {
78
- content: [{ type: 'text', text: 'Tool execution rejected by user.' }],
79
- details: undefined
80
- };
71
+ return createApprovalErrorResult(APPROVAL_ERROR_CODE.USER_REJECTED, USER_REJECTED_APPROVAL_MESSAGE, request.kind, tool.name);
81
72
  }
82
73
  const allowedChoice = (await isApprovedChoiceAllowed?.(request, choice)) ?? true;
83
74
  if (!allowedChoice) {
84
75
  onRejected?.(request);
85
- return {
86
- content: [{ type: 'text', text: 'Tool execution rejected by user.' }],
87
- details: undefined
88
- };
76
+ return createApprovalErrorResult(APPROVAL_ERROR_CODE.USER_REJECTED, USER_REJECTED_APPROVAL_MESSAGE, request.kind, tool.name);
89
77
  }
90
78
  onAccepted?.(request, choice);
91
79
  if (choice === APPROVAL.ACCEPT_ALL) {
@@ -9,8 +9,6 @@ import type { ExtensionContext } from '../extensions/index.js';
9
9
  export declare const APPROVAL: {
10
10
  readonly ACCEPT: "Accept";
11
11
  readonly ACCEPT_ALL: "Accept All";
12
- readonly RUN_FOREGROUND: "Run foreground";
13
- readonly RUN_BACKGROUND: "Run background";
14
12
  readonly ALLOW_ONCE: "Allow Once";
15
13
  readonly ALLOW_FILE: "Always Allow File";
16
14
  readonly ALLOW_FOLDER: "Always Allow Folder";
@@ -61,18 +59,6 @@ export interface BashApprovalData {
61
59
  reason: string;
62
60
  }>;
63
61
  }
64
- export interface TaskSpawnApprovalData {
65
- subagentType: string;
66
- name: string;
67
- query: string;
68
- model?: string;
69
- /** Task spawn approval is all-or-nothing: approved children run as full workers. */
70
- fullWorker: true;
71
- /** True when this subagent can recursively spawn more full-worker children. */
72
- canSpawnSubagents: boolean;
73
- /** Launch mode requested by the tool call before user approval overrides. */
74
- requestedRunInBackground: boolean;
75
- }
76
62
  export interface SwitchModeApprovalData {
77
63
  currentMode: string;
78
64
  targetMode: string;
@@ -8,8 +8,6 @@
8
8
  export const APPROVAL = {
9
9
  ACCEPT: 'Accept',
10
10
  ACCEPT_ALL: 'Accept All',
11
- RUN_FOREGROUND: 'Run foreground',
12
- RUN_BACKGROUND: 'Run background',
13
11
  ALLOW_ONCE: 'Allow Once',
14
12
  ALLOW_FILE: 'Always Allow File',
15
13
  ALLOW_FOLDER: 'Always Allow Folder',
@@ -35,8 +35,6 @@ export async function generateToolSummaryDetailed(input, shortcutLlmProxy, optio
35
35
  { role: 'human', content: userContent }
36
36
  ],
37
37
  max_output_tokens: maxOutputTokens,
38
- effort_level: 'low',
39
- thinking_type: 'off',
40
38
  llmOperation: 'summarize'
41
39
  }, {
42
40
  signal
@@ -23,7 +23,7 @@ export interface ComExecResult {
23
23
  cfTxId?: string;
24
24
  editMode?: boolean;
25
25
  }
26
- export type ApprovalOutcome = 'accepted' | 'failed' | 'reverted' | 'revert-failed' | 'rejected';
26
+ export type ApprovalOutcome = 'accepted' | 'approval-unavailable' | 'failed' | 'reverted' | 'revert-failed' | 'rejected';
27
27
  export interface LocalExecResult {
28
28
  result: ComExecResult;
29
29
  outcome: ApprovalOutcome;
@@ -10,6 +10,7 @@
10
10
  * - `createExcelExecTool()` (COM ToolDefinition wrapper)
11
11
  */
12
12
  import { log } from '../../../../shared/logging/agent-log.js';
13
+ import { INTERACTIVE_APPROVAL_UNAVAILABLE_MESSAGE } from '../../../approvals/approval-errors.js';
13
14
  import { APPROVAL } from '../../../approvals/types.js';
14
15
  import { getApprovalSurface, resolveApprovalExecutionDecision } from '../../../permissions/approval-surface.js';
15
16
  import { getEffectiveExcelHttpUrl } from '../../../xll/endpoint.js';
@@ -60,7 +61,7 @@ function isDangerousExcelLifecycleBypassed(ctx) {
60
61
  }
61
62
  async function requestAlwaysConfirmApproval(approval, ctx, description, dangerousOperations, observability) {
62
63
  if (isDangerousExcelLifecycleBypassed(ctx)) {
63
- return APPROVAL.ACCEPT;
64
+ return { choice: APPROVAL.ACCEPT, unavailable: false };
64
65
  }
65
66
  const request = {
66
67
  kind: 'execute_code',
@@ -85,16 +86,16 @@ async function requestAlwaysConfirmApproval(approval, ctx, description, dangerou
85
86
  });
86
87
  if (decision !== 'prompt' || !approval || !ctx) {
87
88
  observability?.onRejected?.(request);
88
- return APPROVAL.REJECT;
89
+ return { choice: APPROVAL.REJECT, unavailable: decision === 'deny' };
89
90
  }
90
91
  observability?.onRequested?.(request);
91
92
  const choice = await approval.requestApproval(request, ctx);
92
93
  if (choice === APPROVAL.REJECT || choice === undefined) {
93
94
  observability?.onRejected?.(request);
94
- return choice;
95
+ return { choice, unavailable: false };
95
96
  }
96
97
  observability?.onAccepted?.(request, choice);
97
- return choice;
98
+ return { choice, unavailable: false };
98
99
  }
99
100
  // ---------------------------------------------------------------------------
100
101
  // Approval resolution
@@ -146,7 +147,7 @@ export async function resolveApproval(result, approval, postControl, ctx, descri
146
147
  try {
147
148
  await postControl({ control: CONTROL.REVERT, cfTxId });
148
149
  observability?.onReverted?.(request);
149
- return { outcome: 'reverted' };
150
+ return { outcome: 'rejected' };
150
151
  }
151
152
  catch {
152
153
  if (cfTxId != null) {
@@ -239,11 +240,17 @@ export async function executeComLocally(excelHttpUrl, code, options) {
239
240
  const analysis = analyzeComWriteCode(code);
240
241
  const dangerousLifecycleBypassed = analysis.alwaysRequireApproval && isDangerousExcelLifecycleBypassed(ctx);
241
242
  if (analysis.alwaysRequireApproval) {
242
- const choice = await requestAlwaysConfirmApproval(approval, ctx, description, analysis.dangerousOperations, observability);
243
+ const approvalResult = await requestAlwaysConfirmApproval(approval, ctx, description, analysis.dangerousOperations, observability);
244
+ const { choice } = approvalResult;
243
245
  if (choice !== APPROVAL.ACCEPT && choice !== APPROVAL.ACCEPT_ALL) {
244
246
  return {
245
- result: { ok: true, output: 'Excel operation rejected by user.' },
246
- outcome: 'rejected'
247
+ result: {
248
+ ok: true,
249
+ output: approvalResult.unavailable
250
+ ? INTERACTIVE_APPROVAL_UNAVAILABLE_MESSAGE
251
+ : 'Excel operation rejected by user.'
252
+ },
253
+ outcome: approvalResult.unavailable ? 'approval-unavailable' : 'rejected'
247
254
  };
248
255
  }
249
256
  if (choice === APPROVAL.ACCEPT_ALL) {
@@ -264,8 +271,11 @@ export async function executeComLocally(excelHttpUrl, code, options) {
264
271
  });
265
272
  if (executionDecision === 'deny') {
266
273
  return {
267
- result: { ok: true, output: 'Excel operation rejected by user.' },
268
- outcome: 'rejected'
274
+ result: {
275
+ ok: true,
276
+ output: INTERACTIVE_APPROVAL_UNAVAILABLE_MESSAGE
277
+ },
278
+ outcome: 'approval-unavailable'
269
279
  };
270
280
  }
271
281
  let result = await sendExecRequest();
@@ -8,6 +8,7 @@
8
8
  import { Type } from '@sinclair/typebox';
9
9
  import { EXECUTE_CODE } from '../../../../tool-names.js';
10
10
  import { truncateOutput } from '../../../../utils/truncate.js';
11
+ import { APPROVAL_ERROR_CODE, INTERACTIVE_APPROVAL_UNAVAILABLE_MESSAGE, USER_REJECTED_APPROVAL_MESSAGE } from '../../../approvals/approval-errors.js';
11
12
  import { buildLocalExcelHttpUrl, parseExcelHttpPort } from '../../../xll/http-url.js';
12
13
  import { executeComLocally } from './executor.js';
13
14
  const TOOL_NAME = EXECUTE_CODE;
@@ -90,8 +91,26 @@ export function createExcelExecTool(httpPort, approval, observability) {
90
91
  }
91
92
  if (outcome === 'rejected') {
92
93
  return {
93
- content: [{ type: 'text', text: 'Excel operation rejected by user.' }],
94
- details: result
94
+ content: [{ type: 'text', text: USER_REJECTED_APPROVAL_MESSAGE }],
95
+ details: {
96
+ ...result,
97
+ code: APPROVAL_ERROR_CODE.USER_REJECTED,
98
+ approvalKind: EXECUTE_CODE,
99
+ toolName: EXECUTE_CODE
100
+ },
101
+ isError: true
102
+ };
103
+ }
104
+ if (outcome === 'approval-unavailable') {
105
+ return {
106
+ content: [{ type: 'text', text: INTERACTIVE_APPROVAL_UNAVAILABLE_MESSAGE }],
107
+ details: {
108
+ ...result,
109
+ code: APPROVAL_ERROR_CODE.INTERACTIVE_APPROVAL_UNAVAILABLE,
110
+ approvalKind: EXECUTE_CODE,
111
+ toolName: EXECUTE_CODE
112
+ },
113
+ isError: true
95
114
  };
96
115
  }
97
116
  if (outcome === 'failed' || !result.ok) {
@@ -6,7 +6,7 @@
6
6
  */
7
7
  import type { ToolExecutionContext } from '../../core/core-types.js';
8
8
  import type { RuntimeFilesystemPermissionPolicy, RuntimeShellPermissionPolicy } from '../../core/permission-policy.js';
9
- import { type ApprovalChoice, type ApprovalRequest, type BashApprovalData, type FileAccessApprovalData, type TaskSpawnApprovalData } from '../approvals/types.js';
9
+ import { type ApprovalChoice, type ApprovalRequest, type BashApprovalData, type FileAccessApprovalData } from '../approvals/types.js';
10
10
  import type { SettingsManager } from '../settings-manager.js';
11
11
  type RiskyShellOperationRule = {
12
12
  label: string;
@@ -26,13 +26,9 @@ export declare function isFilesystemInvocationSafe(absolutePath: string, access:
26
26
  export declare function applyFilesystemApprovalChoice(choice: ApprovalChoice, request: ApprovalRequest<FileAccessApprovalData>, access: 'read' | 'write', settingsManager: SettingsManager, ctx: ToolExecutionContext | undefined): ToolExecutionContext | undefined;
27
27
  /** Build the approval request payload for a shell command. */
28
28
  export declare function buildShellApprovalRequest(params: Record<string, unknown>, toolName: string): ApprovalRequest<BashApprovalData>;
29
- /** Build the approval request payload for a task subagent spawn. */
30
- export declare function buildTaskSpawnApprovalRequest(payload: TaskSpawnApprovalData): ApprovalRequest<TaskSpawnApprovalData>;
31
29
  /** Check whether the shell policy allows invocations without prompting. */
32
30
  export declare function isShellInvocationSafe(policy: RuntimeShellPermissionPolicy | undefined, command?: string): boolean;
33
31
  /** Record an approved shell command on the tool execution context. */
34
32
  export declare function applyShellApprovalChoice(ctx: ToolExecutionContext | undefined, params: Record<string, unknown>): ToolExecutionContext | undefined;
35
- /** Translate a task-spawn approval choice into a one-shot subagent spawn grant. */
36
- export declare function applyTaskSpawnApprovalChoice(ctx: ToolExecutionContext | undefined, request: ApprovalRequest<TaskSpawnApprovalData>, choice?: ApprovalChoice): ToolExecutionContext | undefined;
37
33
  export {};
38
34
  //# sourceMappingURL=runtime-approval-flow.d.ts.map
@@ -133,16 +133,6 @@ export function buildShellApprovalRequest(params, toolName) {
133
133
  }
134
134
  };
135
135
  }
136
- /** Build the approval request payload for a task subagent spawn. */
137
- export function buildTaskSpawnApprovalRequest(payload) {
138
- return {
139
- kind: 'task',
140
- title: 'Review subagent spawn',
141
- choices: [APPROVAL.RUN_FOREGROUND, APPROVAL.RUN_BACKGROUND, APPROVAL.REJECT],
142
- alwaysRequireExplicitApproval: true,
143
- payload
144
- };
145
- }
146
136
  /** Check whether the shell policy allows invocations without prompting. */
147
137
  export function isShellInvocationSafe(policy, command) {
148
138
  if (command !== undefined && hasRiskyShellOperation(command)) {
@@ -160,22 +150,4 @@ export function applyShellApprovalChoice(ctx, params) {
160
150
  }
161
151
  };
162
152
  }
163
- /** Translate a task-spawn approval choice into a one-shot subagent spawn grant. */
164
- export function applyTaskSpawnApprovalChoice(ctx, request, choice = APPROVAL.ACCEPT) {
165
- const runInBackground = choice === APPROVAL.RUN_BACKGROUND
166
- ? true
167
- : choice === APPROVAL.RUN_FOREGROUND
168
- ? false
169
- : request.payload.requestedRunInBackground;
170
- return {
171
- ...ctx,
172
- // Task spawn approval is a one-shot child launch authorization. Approved
173
- // spawns become full-worker child sessions; the approval does not create a
174
- // reusable grant for later task calls.
175
- subagentSpawnGrant: {
176
- fullWorker: true,
177
- runInBackground
178
- }
179
- };
180
- }
181
153
  //# sourceMappingURL=runtime-approval-flow.js.map
@@ -1,7 +1,7 @@
1
1
  /** Central permission gate for deciding which runtime tool actions require approval. */
2
2
  import type { ToolDefinition } from '../../core/core-types.js';
3
3
  import { BASH, EDIT, EXECUTE_CODE, FIND, GREP, LS, READ, TASK, WRITE } from '../../tool-names.js';
4
- import { type ApprovalGate, type BashApprovalData, type FileAccessApprovalData, type TaskSpawnApprovalData } from '../approvals/types.js';
4
+ import { type ApprovalGate, type BashApprovalData, type FileAccessApprovalData } from '../approvals/types.js';
5
5
  import type { ShortcutClientLogger } from '../observability/client-logging/client-logger.js';
6
6
  import type { SettingsManager } from '../settings-manager.js';
7
7
  export type PermissionedRuntimeToolName = typeof READ | typeof WRITE | typeof EDIT | typeof LS | typeof FIND | typeof GREP | typeof BASH | typeof EXECUTE_CODE | typeof TASK;
@@ -43,7 +43,7 @@ export declare const TOOL_GATES: {
43
43
  readonly kind: "self-gated";
44
44
  };
45
45
  readonly task: {
46
- readonly kind: "task";
46
+ readonly kind: "passthrough";
47
47
  };
48
48
  };
49
49
  export declare const PERMISSIONED_RUNTIME_TOOL_NAMES: PermissionedRuntimeToolName[];
@@ -53,7 +53,6 @@ export interface RegisterRuntimeToolDeps {
53
53
  settingsManager?: SettingsManager;
54
54
  filesystemApproval?: ApprovalGate<FileAccessApprovalData>;
55
55
  shellApproval?: ApprovalGate<BashApprovalData>;
56
- taskApproval?: ApprovalGate<TaskSpawnApprovalData>;
57
56
  observability?: Pick<ShortcutClientLogger, 'info' | 'warn' | 'error'>;
58
57
  }
59
58
  /** Register a runtime tool with the appropriate permission/approval wrapper. */
@@ -2,10 +2,8 @@ import { resolveReadPath, resolveToCwd } from '../../shared/files/path-utils.js'
2
2
  import { BASH, EDIT, EXECUTE_CODE, FIND, GREP, LS, READ, TASK, WRITE } from '../../tool-names.js';
3
3
  import { withPreApproval } from '../approvals/tool-approval.js';
4
4
  import { APPROVAL } from '../approvals/types.js';
5
- import { getSubagent } from '../subagents/index.js';
6
- import { readTaskQueryFile, resolveTaskQuery } from '../tools/task/query.js';
7
5
  import { requirePermissionPolicy } from './require-policy.js';
8
- import { applyFilesystemApprovalChoice, applyShellApprovalChoice, applyTaskSpawnApprovalChoice, buildFilesystemApprovalRequest, buildShellApprovalRequest, buildTaskSpawnApprovalRequest, describeFilesystemApprovalChoice, isFilesystemInvocationSafe, isShellInvocationSafe } from './runtime-approval-flow.js';
6
+ import { applyFilesystemApprovalChoice, applyShellApprovalChoice, buildFilesystemApprovalRequest, buildShellApprovalRequest, describeFilesystemApprovalChoice, isFilesystemInvocationSafe, isShellInvocationSafe } from './runtime-approval-flow.js';
9
7
  export const TOOL_GATES = {
10
8
  [READ]: {
11
9
  kind: 'filesystem',
@@ -39,7 +37,7 @@ export const TOOL_GATES = {
39
37
  },
40
38
  [BASH]: { kind: 'shell' },
41
39
  [EXECUTE_CODE]: { kind: 'self-gated' },
42
- [TASK]: { kind: 'task' }
40
+ [TASK]: { kind: 'passthrough' }
43
41
  };
44
42
  export const PERMISSIONED_RUNTIME_TOOL_NAMES = Object.keys(TOOL_GATES);
45
43
  /** Type guard: check whether a tool name has a registered permission gate. */
@@ -175,80 +173,6 @@ function wrapShellTool(tool, deps) {
175
173
  applyApprovalContext: async (ctx, params) => applyShellApprovalChoice(ctx, params)
176
174
  });
177
175
  }
178
- /** Wrap the task tool with subagent-spawn approval and observability. */
179
- function wrapTaskTool(tool, deps) {
180
- if (!deps.taskApproval) {
181
- return tool;
182
- }
183
- return wrapToolWithAgentApproval(tool, {
184
- approval: deps.taskApproval,
185
- buildRequest: (params) => {
186
- const subagentType = String(params.subagent_type ?? '');
187
- const subagent = getSubagent(subagentType);
188
- let query;
189
- if (typeof params.query_file === 'string' && params.query_file.trim().length > 0) {
190
- try {
191
- query = readTaskQueryFile(params.query_file);
192
- }
193
- catch {
194
- query = params.query_file;
195
- }
196
- }
197
- else {
198
- query = resolveTaskQuery(String(params.query ?? ''));
199
- }
200
- return buildTaskSpawnApprovalRequest({
201
- subagentType: String(params.subagent_type ?? ''),
202
- name: String(params.name ?? ''),
203
- query,
204
- model: typeof params.model === 'string' ? params.model : undefined,
205
- fullWorker: true,
206
- canSpawnSubagents: subagent?.tools.includes(TASK) === true,
207
- requestedRunInBackground: params.run_in_background === true
208
- });
209
- },
210
- isContentSafe: (_params, ctx) => requirePermissionPolicy(ctx, tool.name).dangerouslySkipRuntimePermissions === true,
211
- onRequested: (request) => {
212
- deps.observability?.info({
213
- module: 'tool',
214
- event: 'tool_approval_requested',
215
- data: {
216
- tool_name: tool.name,
217
- approval_kind: 'subagent_spawn',
218
- subagent_type: request.payload.subagentType
219
- }
220
- });
221
- },
222
- onAccepted: (request, choice) => {
223
- deps.observability?.info({
224
- module: 'tool',
225
- event: 'tool_approval_accepted',
226
- data: {
227
- tool_name: tool.name,
228
- approval_kind: 'subagent_spawn',
229
- accept_all: choice === APPROVAL.ACCEPT_ALL,
230
- subagent_type: request.payload.subagentType
231
- }
232
- });
233
- },
234
- onRejected: (request) => {
235
- deps.observability?.warn({
236
- module: 'tool',
237
- event: 'tool_approval_rejected',
238
- data: {
239
- tool_name: tool.name,
240
- approval_kind: 'subagent_spawn',
241
- subagent_type: request.payload.subagentType
242
- }
243
- });
244
- },
245
- isApprovedChoiceAllowed: (_request, choice) => choice === APPROVAL.ACCEPT ||
246
- choice === APPROVAL.RUN_FOREGROUND ||
247
- choice === APPROVAL.RUN_BACKGROUND,
248
- describeApprovedChoice: (request) => `User approved subagent spawn: ${request.payload.name} [${request.payload.subagentType}]`,
249
- applyApprovalContext: async (ctx, _params, request, choice) => applyTaskSpawnApprovalChoice(ctx, request, choice)
250
- });
251
- }
252
176
  /** Register a runtime tool with the appropriate permission/approval wrapper. */
253
177
  export function registerRuntimeTool(tools, tool, deps) {
254
178
  if (!isPermissionedRuntimeToolName(tool.name)) {
@@ -263,10 +187,8 @@ export function registerRuntimeTool(tools, tool, deps) {
263
187
  case 'shell':
264
188
  tools.push(wrapShellTool(permissionedTool, deps));
265
189
  return;
266
- case 'task':
267
- tools.push(wrapTaskTool(permissionedTool, deps));
268
- return;
269
190
  case 'self-gated':
191
+ case 'passthrough':
270
192
  tools.push(permissionedTool);
271
193
  }
272
194
  }
@@ -8,7 +8,7 @@ import { homedir } from 'node:os';
8
8
  import { isAbsolute, join, resolve } from 'node:path';
9
9
  import { CONFIG_DIR_NAME, getAgentDir, getBundledSkillsDir, isNewSheetEnabled } from '../../config.js';
10
10
  import { RuntimeSkillSource } from '../../contracts/agent-resources.js';
11
- import { AGENT_PHILOSOPHY, COMMUNICATION, DATA_FORMATTING, TASK_EXECUTION, WRITING_CODE } from '../../core/prompts/agent-guidelines.js';
11
+ import { COMMUNICATION, DATA_FORMATTING, TASK_EXECUTION, WRITING_CODE } from '../../core/prompts/agent-guidelines.js';
12
12
  import { buildMogHeadlessApiReferenceSection } from '../../utils/mog-headless-api-reference.js';
13
13
  import { inferExternalSkillProviderFromPath } from '../resources/external-skill-roots.js';
14
14
  import { loadSkills } from '../resources/skills.js';
@@ -112,7 +112,7 @@ export function buildCurrentSkillsSection(options = {}) {
112
112
  // ---------------------------------------------------------------------------
113
113
  /** Append action-mode shared guidelines + engine API reference to a sections array. */
114
114
  export function pushActionSharedGuidelines(sections, engine) {
115
- sections.push(AGENT_PHILOSOPHY, TASK_EXECUTION, COMMUNICATION, WRITING_CODE, DATA_FORMATTING, engine.apiGuidelines);
115
+ sections.push(TASK_EXECUTION, COMMUNICATION, WRITING_CODE, DATA_FORMATTING, engine.apiGuidelines);
116
116
  }
117
117
  /** Append read-only shared guidelines + engine API reference to a sections array. */
118
118
  export function pushReadOnlySharedGuidelines(sections, engine) {
@@ -15,15 +15,11 @@
15
15
  * bodies reuse the shared Google converters so the wire format cannot drift from
16
16
  * the built-in and embedded paths.
17
17
  */
18
- import { convertMessages, convertTools, mapStopReasonString } from '../../ai/providers/google-shared.js';
18
+ import { mapStopReasonString } from '../../ai/providers/google-shared.js';
19
+ import { buildGoogleVertexRequest, googleVertexGatewayEndpoint } from '../../ai/providers/google-vertex.js';
19
20
  import { AssistantMessageEventStream } from '../../ai/utils/event-stream.js';
20
21
  import { isContextOverflowErrorMessage } from '../../ai/utils/overflow.js';
21
- import { sanitizeSurrogates } from '../../ai/utils/sanitize-unicode.js';
22
22
  import { extractStructuredHttpErrorPayload, LLMErrorMetadataHeaders, parseStreamErrorPayload, safeModelStreamErrorMessage } from '../../contracts/model-stream.js';
23
- // The gateway fronts Vertex with a fixed project/location; the CLI never needs
24
- // real GCP project credentials. Mirrors the embedded transport's constants.
25
- const GATEWAY_PROJECT = '-';
26
- const GATEWAY_LOCATION = 'global';
27
23
  class GoogleGatewayHttpError extends Error {
28
24
  details;
29
25
  constructor(details) {
@@ -43,49 +39,6 @@ function emptyUsage() {
43
39
  totalTokens: 0
44
40
  };
45
41
  }
46
- function normalizeBaseUrl(baseUrl) {
47
- return baseUrl.replace(/\/+$/, '');
48
- }
49
- function gatewayEndpoint(baseUrl, modelId) {
50
- const model = encodeURIComponent(modelId);
51
- return (`${normalizeBaseUrl(baseUrl)}/v1/projects/${GATEWAY_PROJECT}` +
52
- `/locations/${GATEWAY_LOCATION}/publishers/google/models/${model}:streamGenerateContent?alt=sse`);
53
- }
54
- function mapThinkingLevel(reasoning) {
55
- switch (reasoning) {
56
- case 'minimal':
57
- return 'MINIMAL';
58
- case 'low':
59
- return 'LOW';
60
- case 'medium':
61
- return 'MEDIUM';
62
- case 'high':
63
- case 'xhigh':
64
- return 'HIGH';
65
- default:
66
- return undefined;
67
- }
68
- }
69
- function buildRequestBody(model, context, options) {
70
- const generationConfig = {};
71
- if (options?.maxTokens !== undefined)
72
- generationConfig.maxOutputTokens = options.maxTokens;
73
- if (options?.temperature !== undefined)
74
- generationConfig.temperature = options.temperature;
75
- const thinkingLevel = model.reasoning ? mapThinkingLevel(options?.reasoning) : undefined;
76
- if (thinkingLevel) {
77
- generationConfig.thinkingConfig = { includeThoughts: true, thinkingLevel };
78
- }
79
- const tools = context.tools?.length ? convertTools(context.tools) : undefined;
80
- return {
81
- contents: convertMessages(model, context),
82
- ...(context.systemPrompt
83
- ? { systemInstruction: { parts: [{ text: sanitizeSurrogates(context.systemPrompt) }] } }
84
- : {}),
85
- ...(tools ? { tools } : {}),
86
- ...(Object.keys(generationConfig).length > 0 ? { generationConfig } : {})
87
- };
88
- }
89
42
  /** Parse Vertex SSE frames into decoded JSON payloads. */
90
43
  async function* sseEvents(response) {
91
44
  const parseFrame = (frame) => {
@@ -194,10 +147,10 @@ export function streamSimpleGoogleVertexGateway(model, context, options) {
194
147
  let textIndex;
195
148
  let stopReason = 'stop';
196
149
  try {
197
- const response = await (options?.fetch ?? fetch)(gatewayEndpoint(model.baseUrl, model.id), {
150
+ const response = await (options?.fetch ?? fetch)(`${googleVertexGatewayEndpoint(model.baseUrl, model.id, 'streamGenerateContent')}?alt=sse`, {
198
151
  method: 'POST',
199
152
  headers: { 'content-type': 'application/json', ...options?.headers },
200
- body: JSON.stringify(buildRequestBody(model, context, options)),
153
+ body: JSON.stringify(buildGoogleVertexRequest(model, context, options)),
201
154
  signal: options?.signal
202
155
  });
203
156
  if (!response.ok) {
@@ -107,6 +107,7 @@ export interface ProviderConfigInput {
107
107
  };
108
108
  contextWindow: number;
109
109
  maxTokens: number;
110
+ capabilities?: Model<Api>['capabilities'];
110
111
  headers?: Record<string, string>;
111
112
  compat?: Model<Api>['compat'];
112
113
  }>;