@cydm/pie 2.7.8 → 2.7.9
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.
- package/dist/builtin/extensions/ask-user/index.js +3 -3
- package/dist/builtin/extensions/plan-mode/index.js +3 -18
- package/dist/builtin/extensions/subagent/index.js +10 -6
- package/dist/builtin/extensions/todo/index.js +3 -3
- package/dist/chunks/{chunk-W5B3OXHQ.js → chunk-5SP2H5QK.js} +1 -1
- package/dist/chunks/{chunk-E6F4BTNN.js → chunk-ABZOXNDK.js} +11 -5
- package/dist/chunks/{chunk-P22SYVGO.js → chunk-AX5QEIKP.js} +361 -175
- package/dist/chunks/{chunk-2FEDB5GR.js → chunk-SMGBZQI5.js} +12 -4
- package/dist/chunks/{src-C2CBPEUY.js → src-BQUDKBQ7.js} +2 -2
- package/dist/chunks/{test-stream-LDVUVSUP.js → test-stream-A5KBYYZD.js} +1 -1
- package/dist/cli.js +133 -47
- package/package.json +2 -2
|
@@ -2,7 +2,7 @@ import { createRequire as __createRequire } from "node:module"; const require =
|
|
|
2
2
|
import {
|
|
3
3
|
Agent,
|
|
4
4
|
getToolCallerIdentity
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-5SP2H5QK.js";
|
|
6
6
|
import {
|
|
7
7
|
AssistantMessageEventStream,
|
|
8
8
|
FileSystemGateway,
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
getPlatformConfig,
|
|
13
13
|
hashText,
|
|
14
14
|
streamSimple
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-SMGBZQI5.js";
|
|
16
16
|
import {
|
|
17
17
|
Type
|
|
18
18
|
} from "./chunk-XXGYUYXI.js";
|
|
@@ -899,6 +899,11 @@ function shouldPreserveExecutionStateForUserText(text) {
|
|
|
899
899
|
return CONTINUE_PATTERNS.some((pattern) => pattern.test(trimmed));
|
|
900
900
|
}
|
|
901
901
|
|
|
902
|
+
// ../../packages/shared-headless-capabilities/src/capability.ts
|
|
903
|
+
function defineSharedCapability(definition) {
|
|
904
|
+
return definition;
|
|
905
|
+
}
|
|
906
|
+
|
|
902
907
|
// ../../packages/shared-headless-capabilities/src/tool-policy.ts
|
|
903
908
|
var BUILTIN_TOOL_CAPABILITY_METADATA = {
|
|
904
909
|
search_context: { riskClass: "read_only", concurrencySafe: true, permissionScope: "session", availableInPlanMode: true, allowedForSubagentByDefault: false, maxOutputChars: 2e4 },
|
|
@@ -971,13 +976,51 @@ function getSubagentToolPolicyDecision(tool) {
|
|
|
971
976
|
}
|
|
972
977
|
var DEFAULT_PLAN_MODE_TOOL_NAMES = Object.entries(BUILTIN_TOOL_CAPABILITY_METADATA).filter(([, metadata]) => metadata.availableInPlanMode).map(([name]) => name);
|
|
973
978
|
|
|
974
|
-
// ../../packages/shared-headless-capabilities/src/
|
|
975
|
-
|
|
976
|
-
|
|
979
|
+
// ../../packages/shared-headless-capabilities/src/plan.ts
|
|
980
|
+
var import_shell_quote = __toESM(require_shell_quote(), 1);
|
|
981
|
+
|
|
982
|
+
// ../../packages/shared-headless-capabilities/src/shell-resolution.ts
|
|
983
|
+
function defaultShellKindForPlatform(platform = process.platform) {
|
|
984
|
+
return platform === "win32" ? "powershell" : "bash";
|
|
985
|
+
}
|
|
986
|
+
function resolveRequestShellKind(shell, platform = process.platform) {
|
|
987
|
+
if (shell === "bash" || shell === "powershell" || shell === "cmd") return shell;
|
|
988
|
+
return defaultShellKindForPlatform(platform);
|
|
977
989
|
}
|
|
978
990
|
|
|
979
991
|
// ../../packages/shared-headless-capabilities/src/plan.ts
|
|
980
|
-
var
|
|
992
|
+
var PLAN_POWERSHELL_READ_COMMANDS = new Set([
|
|
993
|
+
"Get-Content",
|
|
994
|
+
"Get-ChildItem",
|
|
995
|
+
"Get-Item",
|
|
996
|
+
"Get-Location",
|
|
997
|
+
"Get-Date",
|
|
998
|
+
"Get-Command",
|
|
999
|
+
"Select-String",
|
|
1000
|
+
"Measure-Object",
|
|
1001
|
+
"Compare-Object",
|
|
1002
|
+
"Test-Path"
|
|
1003
|
+
].map((name) => name.toLowerCase()));
|
|
1004
|
+
var PLAN_POWERSHELL_READ_ALIASES = /* @__PURE__ */ new Set(["cat", "ls", "pwd", "echo", "sort"]);
|
|
1005
|
+
var PLAN_POWERSHELL_SAFE_PARAMETERS = /^(?:-(?:Raw|TotalCount|Head|Tail|First|Last|Wait|LiteralPath|Path|Name|Pattern|Recurse|Filter|Include|Exclude|SimpleMatch|CaseSensitive|Quiet|Word|Line|Character|Encoding|ErrorAction|WarningAction))$/i;
|
|
1006
|
+
var PLAN_POWERSHELL_SEPARATORS = /[;\n\r\t]|[<>]{1,2}|\||&&|\|\|/;
|
|
1007
|
+
var PLAN_POWERSHELL_NON_ASCII = /[^\x20-\x7E]/;
|
|
1008
|
+
var PLAN_POWERSHELL_UNSAFE_TOKENS = /\$\(|`|%\{|[(){}\[\]]|\bsource\b|\.\s+[/~]|\b(bash|sh|zsh|pwsh|powershell|cmd|npm|npx|node|python3?|git)\b/i;
|
|
1009
|
+
function isPlanModeSafePowerShellCommand(command) {
|
|
1010
|
+
const trimmed = command.trim();
|
|
1011
|
+
if (!trimmed) return false;
|
|
1012
|
+
if (PLAN_POWERSHELL_NON_ASCII.test(command)) return false;
|
|
1013
|
+
if (PLAN_POWERSHELL_SEPARATORS.test(trimmed)) return false;
|
|
1014
|
+
if (PLAN_POWERSHELL_UNSAFE_TOKENS.test(trimmed)) return false;
|
|
1015
|
+
const tokens = trimmed.split(/\s+/).filter(Boolean);
|
|
1016
|
+
const head = tokens[0].toLowerCase();
|
|
1017
|
+
if (!head) return false;
|
|
1018
|
+
if (!PLAN_POWERSHELL_READ_COMMANDS.has(head) && !PLAN_POWERSHELL_READ_ALIASES.has(head)) return false;
|
|
1019
|
+
for (const token of tokens.slice(1)) {
|
|
1020
|
+
if (token.startsWith("-") && !PLAN_POWERSHELL_SAFE_PARAMETERS.test(token)) return false;
|
|
1021
|
+
}
|
|
1022
|
+
return true;
|
|
1023
|
+
}
|
|
981
1024
|
var SIMPLE_READ_COMMANDS = /* @__PURE__ */ new Set(["pwd", "ls", "cat", "head", "tail", "wc", "grep", "rg", "which", "type", "echo", "printf", "cd", "true", "false", "tree", "jq", "stat", "file", "du", "df", "basename", "dirname", "date", "uname", "sort", "uniq", "cut", "column", "shasum", "printenv"]);
|
|
982
1025
|
var GIT_READ_SUBCOMMANDS = /* @__PURE__ */ new Set(["status", "log", "diff", "show", "rev-parse", "ls-files", "ls-tree", "blame", "describe", "shortlog", "merge-base"]);
|
|
983
1026
|
var UNSAFE_GIT_FLAGS = /^(?:-c|--config-env|--exec|--output|--ext-diff|--textconv)(?:=|$)/;
|
|
@@ -1095,7 +1138,21 @@ function isReadOnlySegment(words) {
|
|
|
1095
1138
|
}
|
|
1096
1139
|
if (program === "uniq") return isReadOnlyUniq(args);
|
|
1097
1140
|
if (program === "date") {
|
|
1098
|
-
|
|
1141
|
+
const safeFlags = /* @__PURE__ */ new Set(["-u", "--utc", "--universal", "--help", "--version", "--debug"]);
|
|
1142
|
+
const valueFlags = /* @__PURE__ */ new Set(["-d", "--date", "-f", "--file", "-r", "--reference"]);
|
|
1143
|
+
const valueLongFlags = /^(?:--date|--file|--reference|--iso-8601|--rfc-email|--rfc-2822|--rfc-3339)=/;
|
|
1144
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
1145
|
+
const arg = args[index];
|
|
1146
|
+
if (arg.startsWith("+")) continue;
|
|
1147
|
+
if (safeFlags.has(arg) || valueLongFlags.test(arg)) continue;
|
|
1148
|
+
if (valueFlags.has(arg)) {
|
|
1149
|
+
if (index + 1 >= args.length) return false;
|
|
1150
|
+
index += 1;
|
|
1151
|
+
continue;
|
|
1152
|
+
}
|
|
1153
|
+
return false;
|
|
1154
|
+
}
|
|
1155
|
+
return true;
|
|
1099
1156
|
}
|
|
1100
1157
|
if (program === "jq") {
|
|
1101
1158
|
return true;
|
|
@@ -1154,7 +1211,9 @@ ${inlineMatch[1]}`;
|
|
|
1154
1211
|
}
|
|
1155
1212
|
return items;
|
|
1156
1213
|
}
|
|
1157
|
-
function isPlanModeSafeCommand(command) {
|
|
1214
|
+
function isPlanModeSafeCommand(command, shell = "bash") {
|
|
1215
|
+
if (shell === "powershell") return isPlanModeSafePowerShellCommand(command);
|
|
1216
|
+
if (shell === "cmd") return false;
|
|
1158
1217
|
const trimmed = command.trim();
|
|
1159
1218
|
if (!trimmed || /[$`\n\r\0]/.test(trimmed)) return false;
|
|
1160
1219
|
if (/\{[^{}]*\}/.test(trimmed) || /\{\s*,/.test(trimmed)) return false;
|
|
@@ -1994,14 +2053,6 @@ function projectHostContextBlock(block, registry) {
|
|
|
1994
2053
|
};
|
|
1995
2054
|
}
|
|
1996
2055
|
}
|
|
1997
|
-
function leadingHostContextBlock(message) {
|
|
1998
|
-
if (message.role !== "user") return void 0;
|
|
1999
|
-
const content = message.content;
|
|
2000
|
-
if (!Array.isArray(content) || content.length === 0) return void 0;
|
|
2001
|
-
const first = content[0];
|
|
2002
|
-
if (!isHostContextBlock(first)) return void 0;
|
|
2003
|
-
return first;
|
|
2004
|
-
}
|
|
2005
2056
|
function projectionSeparator(projectionText) {
|
|
2006
2057
|
return projectionText.endsWith("\n") && !projectionText.endsWith("\n\n") ? "" : "\n\n";
|
|
2007
2058
|
}
|
|
@@ -2009,23 +2060,40 @@ function projectHostEnvelopes(messages, registry, onProjection) {
|
|
|
2009
2060
|
let changed = false;
|
|
2010
2061
|
const next = [];
|
|
2011
2062
|
for (const message of messages) {
|
|
2012
|
-
|
|
2013
|
-
if (!block) {
|
|
2063
|
+
if (message.role !== "user") {
|
|
2014
2064
|
next.push(message);
|
|
2015
2065
|
continue;
|
|
2016
2066
|
}
|
|
2017
|
-
const outcome = projectHostContextBlock(block, registry);
|
|
2018
|
-
onProjection?.(outcome);
|
|
2019
2067
|
const content = message.content;
|
|
2020
|
-
|
|
2021
|
-
|
|
2068
|
+
if (!Array.isArray(content)) {
|
|
2069
|
+
next.push(message);
|
|
2070
|
+
continue;
|
|
2071
|
+
}
|
|
2072
|
+
let blockCount = 0;
|
|
2073
|
+
while (blockCount < content.length && isHostContextBlock(content[blockCount])) blockCount += 1;
|
|
2074
|
+
if (blockCount === 0) {
|
|
2075
|
+
next.push(message);
|
|
2076
|
+
continue;
|
|
2077
|
+
}
|
|
2078
|
+
const outcomes = [];
|
|
2079
|
+
for (let i = 0; i < blockCount; i++) {
|
|
2080
|
+
const outcome = projectHostContextBlock(content[i], registry);
|
|
2081
|
+
outcomes.push(outcome);
|
|
2082
|
+
onProjection?.(outcome);
|
|
2083
|
+
}
|
|
2084
|
+
const rest = content.slice(blockCount);
|
|
2085
|
+
let text = outcomes[outcomes.length - 1].text;
|
|
2086
|
+
for (let i = outcomes.length - 2; i >= 0; i--) {
|
|
2087
|
+
text = `${outcomes[i].text}${projectionSeparator(outcomes[i].text)}${text}`;
|
|
2088
|
+
}
|
|
2089
|
+
const separator = projectionSeparator(outcomes[outcomes.length - 1].text);
|
|
2022
2090
|
const first = rest[0];
|
|
2023
2091
|
let projectedContent;
|
|
2024
2092
|
if (first && first.type === "text" && typeof first.text === "string") {
|
|
2025
|
-
const merged = first.text.trim().length > 0 ? `${
|
|
2093
|
+
const merged = first.text.trim().length > 0 ? `${text}${separator}${first.text}` : text;
|
|
2026
2094
|
projectedContent = [{ ...first, text: merged }, ...rest.slice(1)];
|
|
2027
2095
|
} else {
|
|
2028
|
-
projectedContent = [{ type: "text", text
|
|
2096
|
+
projectedContent = [{ type: "text", text }, ...rest];
|
|
2029
2097
|
}
|
|
2030
2098
|
next.push({ ...message, content: projectedContent });
|
|
2031
2099
|
changed = true;
|
|
@@ -8160,7 +8228,10 @@ function withSubagentRunContext(stream, hooks) {
|
|
|
8160
8228
|
${SUBAGENT_FINALIZATION_HINT}` } : context, options);
|
|
8161
8229
|
};
|
|
8162
8230
|
}
|
|
8163
|
-
function
|
|
8231
|
+
function isRetryableSubagentFailureFrom(facts) {
|
|
8232
|
+
if (facts.retryable === false) return false;
|
|
8233
|
+
if (facts.replayClass === "stream_lost" || facts.replayClass === "stream_lost_partial") return true;
|
|
8234
|
+
const message = facts.errorMessage ?? "";
|
|
8164
8235
|
const remoteClosure = /SSE stream (?:aborted|closed before end|ended before response completed)/i.test(message);
|
|
8165
8236
|
const classificationText = message.replace(/econnaborted/ig, "").replace(/SSE stream aborted/ig, "remote stream closed");
|
|
8166
8237
|
if (/\b(?:400|401|403|404|422|429)\b|quota|weekly|monthly|limit reached|exhausted|unauthorized|authentication|invalid|protocol|stopReason=length|token limit|abort/i.test(classificationText)) return false;
|
|
@@ -8178,6 +8249,13 @@ function cancellableBackoff(ms, signal) {
|
|
|
8178
8249
|
if (signal?.aborted) finish();
|
|
8179
8250
|
});
|
|
8180
8251
|
}
|
|
8252
|
+
function factsOf(error) {
|
|
8253
|
+
if (error instanceof Error) {
|
|
8254
|
+
const carrier = error;
|
|
8255
|
+
return { errorMessage: error.message, retryable: carrier.retryable, replayClass: carrier.replayClass };
|
|
8256
|
+
}
|
|
8257
|
+
return { errorMessage: String(error) };
|
|
8258
|
+
}
|
|
8181
8259
|
function withSubagentResponseRecovery(stream, backoffMs = 2e3, onRetry, onActivity, hooks) {
|
|
8182
8260
|
return async (model, context, options) => {
|
|
8183
8261
|
for (let attempt = 0; ; attempt++) {
|
|
@@ -8225,7 +8303,7 @@ function withSubagentResponseRecovery(stream, backoffMs = 2e3, onRetry, onActivi
|
|
|
8225
8303
|
message = terminal;
|
|
8226
8304
|
} catch (error) {
|
|
8227
8305
|
finishUsage?.();
|
|
8228
|
-
if (!options?.signal?.aborted && attempt < 2 &&
|
|
8306
|
+
if (!options?.signal?.aborted && attempt < 2 && isRetryableSubagentFailureFrom(factsOf(error))) {
|
|
8229
8307
|
try {
|
|
8230
8308
|
onRetry?.();
|
|
8231
8309
|
} catch {
|
|
@@ -8236,7 +8314,7 @@ function withSubagentResponseRecovery(stream, backoffMs = 2e3, onRetry, onActivi
|
|
|
8236
8314
|
throw error;
|
|
8237
8315
|
}
|
|
8238
8316
|
if (options?.signal?.aborted) throw new Error("Subagent aborted by parent");
|
|
8239
|
-
if (message.stopReason === "error" && attempt < 2 &&
|
|
8317
|
+
if (message.stopReason === "error" && attempt < 2 && isRetryableSubagentFailureFrom({ errorMessage: message.errorMessage, retryable: message.retryable, replayClass: message.replayClass })) {
|
|
8240
8318
|
try {
|
|
8241
8319
|
onRetry?.();
|
|
8242
8320
|
} catch {
|
|
@@ -8385,8 +8463,16 @@ var PROTECTED_POSIX_PATHS = /* @__PURE__ */ new Set([
|
|
|
8385
8463
|
"/Volumes"
|
|
8386
8464
|
]);
|
|
8387
8465
|
var POWERSHELL_DESTRUCTIVE_PATTERNS = [
|
|
8388
|
-
|
|
8389
|
-
|
|
8466
|
+
// PowerShell resolves these aliases before execution. The classifier must
|
|
8467
|
+
// treat the aliases exactly like their canonical cmdlets; otherwise a
|
|
8468
|
+
// guarded shell can run `ri -Recurse -Force` without the confirmation that
|
|
8469
|
+
// `Remove-Item -Recurse -Force` receives.
|
|
8470
|
+
{ pattern: /\b(?:Remove-Item|ri|rm|rmdir|del|erase|rd)\b[^;\n|]*(?:-Recurse|-Force)\b/i, warning: "may recursively or forcefully remove files", commandClass: "filesystem_write" },
|
|
8471
|
+
{ pattern: /\b(?:Remove-Item|ri|rm|rmdir|del|erase|rd)\b[^;\n|]*(?:HKLM:|HKCU:|Registry::)/i, warning: "may remove registry entries", commandClass: "infra_destructive" },
|
|
8472
|
+
// These write aliases are not all destructive in the recursive-delete sense,
|
|
8473
|
+
// but they can overwrite or create arbitrary files. Keep them behind the
|
|
8474
|
+
// same explicit shell confirmation boundary as other PowerShell writes.
|
|
8475
|
+
{ pattern: /\b(?:Set-Content|sc|set|Add-Content|ac|add|New-Item|ni|md|mkdir|Copy-Item|cpi|cp|copy|Move-Item|mi|mv|move|Rename-Item|rni|ren)\b/i, warning: "may write or overwrite files", commandClass: "filesystem_write" },
|
|
8390
8476
|
{ pattern: /\b(Set-ExecutionPolicy|Start-Process\b[^;\n|]*-Verb\s+RunAs)\b/i, warning: "may change execution policy or request elevation", commandClass: "privilege_escalation" },
|
|
8391
8477
|
{ pattern: /\b(Stop-Computer|Restart-Computer)\b/i, warning: "may stop or restart the machine", commandClass: "infra_destructive" },
|
|
8392
8478
|
{ pattern: /(^|[;|&\n])\s*(?:Invoke-Expression|iex)\b/i, warning: "evaluates a dynamically constructed string as code", commandClass: "privilege_escalation" },
|
|
@@ -8411,9 +8497,6 @@ function lastPipelineCommand(command) {
|
|
|
8411
8497
|
const segments = command.split("|").map((part) => part.trim()).filter(Boolean);
|
|
8412
8498
|
return segments[segments.length - 1] || command;
|
|
8413
8499
|
}
|
|
8414
|
-
function classifyBashCommand(command, options) {
|
|
8415
|
-
return classifyShellCommand(command, "bash", options);
|
|
8416
|
-
}
|
|
8417
8500
|
function splitShellSegments(command) {
|
|
8418
8501
|
const segments = [];
|
|
8419
8502
|
let current = "";
|
|
@@ -8595,6 +8678,66 @@ function resolveStaticCwdTarget(target, cwd, root) {
|
|
|
8595
8678
|
if (resolved !== normalizedRoot && !isStrictDescendant(resolved, normalizedRoot)) return void 0;
|
|
8596
8679
|
return resolved;
|
|
8597
8680
|
}
|
|
8681
|
+
var DYNAMIC_EXECUTION_WARNING = "may execute nested shell or interpreter code";
|
|
8682
|
+
function executableName(word) {
|
|
8683
|
+
const normalized = word.replace(/\\/g, "/").toLowerCase();
|
|
8684
|
+
const base = normalized.slice(normalized.lastIndexOf("/") + 1);
|
|
8685
|
+
return base.endsWith(".exe") ? base.slice(0, -4) : base;
|
|
8686
|
+
}
|
|
8687
|
+
function hasDynamicExecutionInvocation(words) {
|
|
8688
|
+
if (words.length === 0) return false;
|
|
8689
|
+
const program = executableName(words[0]);
|
|
8690
|
+
if (program === "env" || program === "command" || program === "exec") {
|
|
8691
|
+
let index = 1;
|
|
8692
|
+
while (index < words.length && (words[index].startsWith("-") || /^[A-Za-z_][A-Za-z0-9_]*=/.test(words[index]))) index += 1;
|
|
8693
|
+
return index < words.length && hasDynamicExecutionInvocation(words.slice(index));
|
|
8694
|
+
}
|
|
8695
|
+
if (["bash", "sh", "zsh", "dash", "ksh", "fish"].includes(program)) {
|
|
8696
|
+
return words.slice(1).some((word) => /^-[^-]*c$/i.test(word) || /^--command(?:=|$)/i.test(word));
|
|
8697
|
+
}
|
|
8698
|
+
if (["pwsh", "powershell"].includes(program)) {
|
|
8699
|
+
return words.slice(1).some((word) => /^-(?:c|command|encodedcommand|e|file)(?:=|$)/i.test(word));
|
|
8700
|
+
}
|
|
8701
|
+
if (program === "cmd") {
|
|
8702
|
+
return words.slice(1).some((word) => /^\/(?:c|k)$/i.test(word));
|
|
8703
|
+
}
|
|
8704
|
+
if (["python", "python3", "python2", "perl", "ruby"].includes(program)) {
|
|
8705
|
+
return words.slice(1).some((word) => /^(?:-c|-e|-m)$/i.test(word));
|
|
8706
|
+
}
|
|
8707
|
+
if (program === "node") {
|
|
8708
|
+
return words.slice(1).some((word) => /^(?:-e|--eval|-p|--print|-r|--require)$/i.test(word));
|
|
8709
|
+
}
|
|
8710
|
+
if (program === "find") {
|
|
8711
|
+
return words.slice(1).some((word) => /^-(?:exec|execdir|ok|okdir)$/.test(word));
|
|
8712
|
+
}
|
|
8713
|
+
if (program === "rg") {
|
|
8714
|
+
return words.slice(1).some((word) => /^--pre(?:=|$)|^--pre-glob(?:=|$)/.test(word));
|
|
8715
|
+
}
|
|
8716
|
+
if (program === "xargs") {
|
|
8717
|
+
const optionsWithValues = /* @__PURE__ */ new Set(["-a", "-d", "-E", "-I", "-L", "-n", "-P", "-s"]);
|
|
8718
|
+
let index = 1;
|
|
8719
|
+
while (index < words.length && words[index].startsWith("-")) {
|
|
8720
|
+
if (optionsWithValues.has(words[index])) index += 1;
|
|
8721
|
+
index += 1;
|
|
8722
|
+
}
|
|
8723
|
+
return index < words.length && hasDynamicExecutionInvocation(words.slice(index));
|
|
8724
|
+
}
|
|
8725
|
+
return false;
|
|
8726
|
+
}
|
|
8727
|
+
function dynamicExecutionWarnings(command) {
|
|
8728
|
+
const warnings = [];
|
|
8729
|
+
for (const segment of splitShellSegments(command)) {
|
|
8730
|
+
const words = splitShellWords(segment);
|
|
8731
|
+
if (words) {
|
|
8732
|
+
if (hasDynamicExecutionInvocation(words)) warnings.push(DYNAMIC_EXECUTION_WARNING);
|
|
8733
|
+
continue;
|
|
8734
|
+
}
|
|
8735
|
+
if (/^(?:[A-Za-z]:[\\/]|[./])?(?:bash|sh|zsh|dash|ksh|fish|pwsh|powershell|cmd|python\d*|node|perl|ruby)\b[^|;&\n]*(?:\s-c(?:\s|$)|\s--?(?:command|encodedcommand|eval|execute|file)(?:[=\s]|$)|\s\/(?:c|k)(?:\s|$))/i.test(segment.trim())) {
|
|
8736
|
+
warnings.push(DYNAMIC_EXECUTION_WARNING);
|
|
8737
|
+
}
|
|
8738
|
+
}
|
|
8739
|
+
return [...new Set(warnings)];
|
|
8740
|
+
}
|
|
8598
8741
|
function isStaticallyScopedRecursiveForceRemove(command, options) {
|
|
8599
8742
|
if (!options?.cwd) return false;
|
|
8600
8743
|
const root = options.sandboxRoot || options.cwd;
|
|
@@ -8636,6 +8779,12 @@ function classifyShellCommand(command, shell = "bash", options) {
|
|
|
8636
8779
|
destructive = true;
|
|
8637
8780
|
}
|
|
8638
8781
|
}
|
|
8782
|
+
const dynamicWarnings = dynamicExecutionWarnings(command);
|
|
8783
|
+
if (dynamicWarnings.length > 0) {
|
|
8784
|
+
warnings.push(...dynamicWarnings);
|
|
8785
|
+
commandClass = "unknown_shell";
|
|
8786
|
+
destructive = true;
|
|
8787
|
+
}
|
|
8639
8788
|
for (const entry of destructivePatterns) {
|
|
8640
8789
|
if (entry.pattern.test(command)) {
|
|
8641
8790
|
warnings.push(entry.warning);
|
|
@@ -8811,7 +8960,8 @@ function wrapBashGuard(tool, plan) {
|
|
|
8811
8960
|
Subagent guarded mode blocks destructive shell commands while preserving the parent's execution checks. Destructive commands are blocked; normal diagnostic, search, test, and build commands are allowed.`,
|
|
8812
8961
|
execute: async (toolCallId, params, signal, onUpdate) => {
|
|
8813
8962
|
const command = typeof params?.command === "string" ? params.command : "";
|
|
8814
|
-
const
|
|
8963
|
+
const shell = resolveRequestShellKind(params?.shell);
|
|
8964
|
+
const classification = classifyShellCommand(command, shell);
|
|
8815
8965
|
if (classification.destructive) {
|
|
8816
8966
|
const reason = `destructive shell command blocked for subagent: ${classification.riskWarnings.join("; ")}`;
|
|
8817
8967
|
plan.toolsExcluded.push({ name: tool.name, reason });
|
|
@@ -9427,7 +9577,11 @@ ${DELEGATION_REPORT_INSTRUCTION}`;
|
|
|
9427
9577
|
throw new Error(`Subagent output token limit reached (stopReason=length): the provider cut the final response before the report was produced${messages.some(messageHasOwnText) ? " (earlier-turn narration discarded)" : ", no text response"}. The output/thinking budget was too small for this task at its reasoning level. Rerun with a narrower task or a lower thinkingLevel.`);
|
|
9428
9578
|
}
|
|
9429
9579
|
const detail = terminalError ? `: ${terminalError.slice(0, 200)}` : "";
|
|
9430
|
-
|
|
9580
|
+
const failure = new Error(`Subagent response failed (provider/transport failure before the report was produced, stopReason=${terminalStopReason ?? "none"}${collectedResponse ? ", partial transcript discarded" : ", no text response"})${detail}`);
|
|
9581
|
+
const carrier = failure;
|
|
9582
|
+
carrier.retryable = lastAssistant?.retryable;
|
|
9583
|
+
carrier.replayClass = lastAssistant?.replayClass;
|
|
9584
|
+
throw failure;
|
|
9431
9585
|
}
|
|
9432
9586
|
let response;
|
|
9433
9587
|
if (!collectedResponse) {
|
|
@@ -9445,6 +9599,7 @@ ${DELEGATION_REPORT_INSTRUCTION}`;
|
|
|
9445
9599
|
}
|
|
9446
9600
|
const durationMs = Date.now() - startTime;
|
|
9447
9601
|
task.status = "completed";
|
|
9602
|
+
task.failure = void 0;
|
|
9448
9603
|
observeDelegationPhase(task.observation, "completed");
|
|
9449
9604
|
task.result = response;
|
|
9450
9605
|
task.details = {
|
|
@@ -9471,6 +9626,12 @@ ${DELEGATION_REPORT_INSTRUCTION}`;
|
|
|
9471
9626
|
observeDelegationPhase(task.observation, timedOut ? "deadline" : signal?.aborted ? "cancelled" : "failed");
|
|
9472
9627
|
phaseProgress(task.observation.phase);
|
|
9473
9628
|
task.error = errorMessage.slice(0, 2e3);
|
|
9629
|
+
const failureCarrier = error;
|
|
9630
|
+
if (failureCarrier && (failureCarrier.retryable !== void 0 || failureCarrier.replayClass !== void 0)) {
|
|
9631
|
+
task.failure = { ...failureCarrier.retryable !== void 0 ? { retryable: failureCarrier.retryable } : {}, ...failureCarrier.replayClass !== void 0 ? { replayClass: failureCarrier.replayClass } : {} };
|
|
9632
|
+
} else {
|
|
9633
|
+
task.failure = void 0;
|
|
9634
|
+
}
|
|
9474
9635
|
task.report ??= parseDelegationReport(void 0, task.id);
|
|
9475
9636
|
task.parentHandoffRequired = isParentHandoffRequired(task);
|
|
9476
9637
|
task.completedAt = Date.now();
|
|
@@ -9807,7 +9968,7 @@ ${SPAWN_USAGE_HINT}` }],
|
|
|
9807
9968
|
await run(task, toolContext.reportProgress, signal);
|
|
9808
9969
|
if (task.wasRecall || task.mode !== "read" || task.status !== "failed" || !task.error) return;
|
|
9809
9970
|
if (signal?.aborted) return;
|
|
9810
|
-
if (!
|
|
9971
|
+
if (!isRetryableSubagentFailureFrom({ errorMessage: task.error, retryable: task.failure?.retryable, replayClass: task.failure?.replayClass })) return;
|
|
9811
9972
|
observeDelegationPhase(task.observation, "task_replay");
|
|
9812
9973
|
const settleMs = Math.max(0, (deps.transientRetryBackoffMs ?? 2e3) * 10);
|
|
9813
9974
|
toolContext.reportProgress?.({ message: `[${task.name}] Provider/transport failure \u2014 replaying the read task once after ${Math.round(settleMs / 1e3)}s`, increment: 0 });
|
|
@@ -9815,6 +9976,7 @@ ${SPAWN_USAGE_HINT}` }],
|
|
|
9815
9976
|
if (signal.aborted) {
|
|
9816
9977
|
task.status = "cancelled";
|
|
9817
9978
|
task.error = "Subagent cancelled during replay backoff";
|
|
9979
|
+
task.failure = void 0;
|
|
9818
9980
|
observeDelegationPhase(task.observation, "cancelled");
|
|
9819
9981
|
task.completedAt = Date.now();
|
|
9820
9982
|
return;
|
|
@@ -9824,6 +9986,7 @@ ${SPAWN_USAGE_HINT}` }],
|
|
|
9824
9986
|
task.runtimeEvidence = [];
|
|
9825
9987
|
task.reportedEvidence = [];
|
|
9826
9988
|
task.error = void 0;
|
|
9989
|
+
task.failure = void 0;
|
|
9827
9990
|
task.report = void 0;
|
|
9828
9991
|
task.result = void 0;
|
|
9829
9992
|
task.details = void 0;
|
|
@@ -9877,6 +10040,10 @@ ${SPAWN_USAGE_HINT}` }],
|
|
|
9877
10040
|
observation: task.observation,
|
|
9878
10041
|
parentHandoffRequired: task.parentHandoffRequired,
|
|
9879
10042
|
failureReason: task.error,
|
|
10043
|
+
// Structured provider verdict so the parent model can distinguish
|
|
10044
|
+
// stream loss (safe to re-dispatch; no tool calls executed) from hard
|
|
10045
|
+
// provider vetoes (auth/quota/config — not recoverable here).
|
|
10046
|
+
failure: task.failure,
|
|
9880
10047
|
details: task.details
|
|
9881
10048
|
})),
|
|
9882
10049
|
totalDuration,
|
|
@@ -10534,6 +10701,164 @@ function createAskUserCapability() {
|
|
|
10534
10701
|
};
|
|
10535
10702
|
}
|
|
10536
10703
|
|
|
10704
|
+
// ../../packages/shared-headless-capabilities/src/policy-enforcer.ts
|
|
10705
|
+
var POLICY_ENFORCED = /* @__PURE__ */ Symbol.for("pie.capabilityPolicy.enforced");
|
|
10706
|
+
function evaluateToolPermission(tool, context = {}) {
|
|
10707
|
+
const mode = context.mode ?? "normal";
|
|
10708
|
+
const metadata = getToolCapabilityMetadata(tool);
|
|
10709
|
+
const base = describeToolPolicyDecision(tool, mode);
|
|
10710
|
+
if (!metadata && mode === "normal") {
|
|
10711
|
+
return {
|
|
10712
|
+
disposition: "allow",
|
|
10713
|
+
allowed: true,
|
|
10714
|
+
reason: "unclassified_tool",
|
|
10715
|
+
policyReason: "unclassified_tool",
|
|
10716
|
+
mode,
|
|
10717
|
+
yoloMode: context.yoloMode
|
|
10718
|
+
};
|
|
10719
|
+
}
|
|
10720
|
+
if (!metadata || !base.allowed) {
|
|
10721
|
+
return {
|
|
10722
|
+
disposition: "deny",
|
|
10723
|
+
allowed: false,
|
|
10724
|
+
reason: base.reason ?? "tool not allowed by runtime policy",
|
|
10725
|
+
policyReason: base.reason ?? "tool not allowed by runtime policy",
|
|
10726
|
+
mode,
|
|
10727
|
+
yoloMode: context.yoloMode,
|
|
10728
|
+
riskClass: metadata?.riskClass,
|
|
10729
|
+
permissionScope: metadata?.permissionScope,
|
|
10730
|
+
requiresPermission: metadata?.requiresPermission
|
|
10731
|
+
};
|
|
10732
|
+
}
|
|
10733
|
+
const requiresConfirmation = Boolean(metadata.highRisk || metadata.requiresPermission);
|
|
10734
|
+
if (!requiresConfirmation || context.yoloMode || context.confirmationPolicy === "allow") {
|
|
10735
|
+
return {
|
|
10736
|
+
disposition: "allow",
|
|
10737
|
+
allowed: true,
|
|
10738
|
+
mode,
|
|
10739
|
+
yoloMode: context.yoloMode,
|
|
10740
|
+
riskClass: metadata.riskClass,
|
|
10741
|
+
permissionScope: metadata.permissionScope,
|
|
10742
|
+
requiresPermission: requiresConfirmation
|
|
10743
|
+
};
|
|
10744
|
+
}
|
|
10745
|
+
if (context.confirmationPolicy === "deny" || mode === "subagent") {
|
|
10746
|
+
const reason = mode === "subagent" ? "subagent cannot request interactive permission" : "permission confirmation is unavailable";
|
|
10747
|
+
return {
|
|
10748
|
+
disposition: "deny",
|
|
10749
|
+
allowed: false,
|
|
10750
|
+
reason,
|
|
10751
|
+
policyReason: reason,
|
|
10752
|
+
mode,
|
|
10753
|
+
yoloMode: context.yoloMode,
|
|
10754
|
+
riskClass: metadata.riskClass,
|
|
10755
|
+
permissionScope: metadata.permissionScope,
|
|
10756
|
+
requiresPermission: true
|
|
10757
|
+
};
|
|
10758
|
+
}
|
|
10759
|
+
return {
|
|
10760
|
+
disposition: "confirm",
|
|
10761
|
+
allowed: false,
|
|
10762
|
+
reason: "permission confirmation required",
|
|
10763
|
+
policyReason: "permission confirmation required",
|
|
10764
|
+
mode,
|
|
10765
|
+
yoloMode: context.yoloMode,
|
|
10766
|
+
riskClass: metadata.riskClass,
|
|
10767
|
+
permissionScope: metadata.permissionScope,
|
|
10768
|
+
requiresPermission: true
|
|
10769
|
+
};
|
|
10770
|
+
}
|
|
10771
|
+
function blockedResult(toolName, decision) {
|
|
10772
|
+
return {
|
|
10773
|
+
content: [
|
|
10774
|
+
{
|
|
10775
|
+
type: "text",
|
|
10776
|
+
text: `Blocked ${toolName}: ${decision.reason ?? decision.policyReason ?? "permission denied"}`
|
|
10777
|
+
}
|
|
10778
|
+
],
|
|
10779
|
+
details: { permissionDecision: decision },
|
|
10780
|
+
isError: true
|
|
10781
|
+
};
|
|
10782
|
+
}
|
|
10783
|
+
function planModeShellCommandBlocked(target, args) {
|
|
10784
|
+
const metadata = getToolCapabilityMetadata(target);
|
|
10785
|
+
if (!metadata?.executesShell) return void 0;
|
|
10786
|
+
const command = args?.command;
|
|
10787
|
+
if (typeof command !== "string") {
|
|
10788
|
+
return `Plan mode: shell tool received no command to validate. Use plan_scratch for temporary drafts, submit the finished plan with plan_submit, or toggle Plan mode off (/tools/plan) to execute.`;
|
|
10789
|
+
}
|
|
10790
|
+
const shell = resolveRequestShellKind(args?.shell);
|
|
10791
|
+
if (isPlanModeSafeCommand(command, shell)) return void 0;
|
|
10792
|
+
return `Plan mode: command "${command}" is not a read-only ${shell} command. Use plan_scratch for temporary drafts, submit the finished plan with plan_submit, or toggle Plan mode off (/tools/plan) to execute.`;
|
|
10793
|
+
}
|
|
10794
|
+
function mergePermissionDetails(details, decision) {
|
|
10795
|
+
if (details && typeof details === "object" && !Array.isArray(details)) {
|
|
10796
|
+
const record = details;
|
|
10797
|
+
if (record.permissionDecision) {
|
|
10798
|
+
return { ...record, capabilityPolicyDecision: decision };
|
|
10799
|
+
}
|
|
10800
|
+
return { ...record, permissionDecision: decision };
|
|
10801
|
+
}
|
|
10802
|
+
return { permissionDecision: decision };
|
|
10803
|
+
}
|
|
10804
|
+
function createPolicyEnforcedTool(tool, options = {}) {
|
|
10805
|
+
const marker = tool[POLICY_ENFORCED];
|
|
10806
|
+
const intactWrapper = !!marker && marker.wrapperExecute === tool.execute;
|
|
10807
|
+
if (intactWrapper && marker.getContext === options.getContext && marker.permissionProvider === options.permissionProvider) {
|
|
10808
|
+
return tool;
|
|
10809
|
+
}
|
|
10810
|
+
const target = intactWrapper ? marker.base : tool;
|
|
10811
|
+
const wrapped = {
|
|
10812
|
+
...target,
|
|
10813
|
+
execute: async (toolCallId, args, signal, onUpdate) => {
|
|
10814
|
+
let decision = evaluateToolPermission(target, options.getContext?.());
|
|
10815
|
+
if (decision.disposition === "confirm") {
|
|
10816
|
+
const approved = await options.permissionProvider?.confirm({ toolName: target.name, args, decision }).catch(() => false);
|
|
10817
|
+
if (!approved) {
|
|
10818
|
+
return blockedResult(target.name, {
|
|
10819
|
+
...decision,
|
|
10820
|
+
disposition: "deny",
|
|
10821
|
+
reason: "permission denied by user",
|
|
10822
|
+
policyReason: "permission denied by user"
|
|
10823
|
+
});
|
|
10824
|
+
}
|
|
10825
|
+
decision = {
|
|
10826
|
+
...decision,
|
|
10827
|
+
disposition: "allow",
|
|
10828
|
+
allowed: true,
|
|
10829
|
+
reason: void 0,
|
|
10830
|
+
policyReason: void 0
|
|
10831
|
+
};
|
|
10832
|
+
}
|
|
10833
|
+
if (!decision.allowed) return blockedResult(target.name, decision);
|
|
10834
|
+
const planShellReason = (options.getContext?.().mode ?? "normal") === "plan" ? planModeShellCommandBlocked(target, args) : void 0;
|
|
10835
|
+
if (planShellReason) {
|
|
10836
|
+
return blockedResult(target.name, {
|
|
10837
|
+
...decision,
|
|
10838
|
+
allowed: false,
|
|
10839
|
+
reason: planShellReason,
|
|
10840
|
+
policyReason: "plan_mode_non_read_only_shell_command"
|
|
10841
|
+
});
|
|
10842
|
+
}
|
|
10843
|
+
const result = await target.execute(toolCallId, args, signal, onUpdate);
|
|
10844
|
+
return {
|
|
10845
|
+
...result,
|
|
10846
|
+
details: mergePermissionDetails(result.details, decision)
|
|
10847
|
+
};
|
|
10848
|
+
}
|
|
10849
|
+
};
|
|
10850
|
+
wrapped[POLICY_ENFORCED] = {
|
|
10851
|
+
getContext: options.getContext,
|
|
10852
|
+
permissionProvider: options.permissionProvider,
|
|
10853
|
+
wrapperExecute: wrapped.execute,
|
|
10854
|
+
base: target
|
|
10855
|
+
};
|
|
10856
|
+
return wrapped;
|
|
10857
|
+
}
|
|
10858
|
+
function createPolicyEnforcedTools(tools, options = {}) {
|
|
10859
|
+
return tools.map((tool) => createPolicyEnforcedTool(tool, options));
|
|
10860
|
+
}
|
|
10861
|
+
|
|
10537
10862
|
// ../../packages/shared-headless-capabilities/src/builtin/fs/read.ts
|
|
10538
10863
|
import * as nodePath from "node:path";
|
|
10539
10864
|
|
|
@@ -16937,144 +17262,6 @@ function maybeAdvanceTodoExecutionState(state, signal) {
|
|
|
16937
17262
|
};
|
|
16938
17263
|
}
|
|
16939
17264
|
|
|
16940
|
-
// ../../packages/shared-headless-capabilities/src/policy-enforcer.ts
|
|
16941
|
-
var POLICY_ENFORCED = /* @__PURE__ */ Symbol.for("pie.capabilityPolicy.enforced");
|
|
16942
|
-
function evaluateToolPermission(tool, context = {}) {
|
|
16943
|
-
const mode = context.mode ?? "normal";
|
|
16944
|
-
const metadata = getToolCapabilityMetadata(tool);
|
|
16945
|
-
const base = describeToolPolicyDecision(tool, mode);
|
|
16946
|
-
if (!metadata && mode === "normal") {
|
|
16947
|
-
return {
|
|
16948
|
-
disposition: "allow",
|
|
16949
|
-
allowed: true,
|
|
16950
|
-
reason: "unclassified_tool",
|
|
16951
|
-
policyReason: "unclassified_tool",
|
|
16952
|
-
mode,
|
|
16953
|
-
yoloMode: context.yoloMode
|
|
16954
|
-
};
|
|
16955
|
-
}
|
|
16956
|
-
if (!metadata || !base.allowed) {
|
|
16957
|
-
return {
|
|
16958
|
-
disposition: "deny",
|
|
16959
|
-
allowed: false,
|
|
16960
|
-
reason: base.reason ?? "tool not allowed by runtime policy",
|
|
16961
|
-
policyReason: base.reason ?? "tool not allowed by runtime policy",
|
|
16962
|
-
mode,
|
|
16963
|
-
yoloMode: context.yoloMode,
|
|
16964
|
-
riskClass: metadata?.riskClass,
|
|
16965
|
-
permissionScope: metadata?.permissionScope,
|
|
16966
|
-
requiresPermission: metadata?.requiresPermission
|
|
16967
|
-
};
|
|
16968
|
-
}
|
|
16969
|
-
const requiresConfirmation = Boolean(metadata.highRisk || metadata.requiresPermission);
|
|
16970
|
-
if (!requiresConfirmation || context.yoloMode || context.confirmationPolicy === "allow") {
|
|
16971
|
-
return {
|
|
16972
|
-
disposition: "allow",
|
|
16973
|
-
allowed: true,
|
|
16974
|
-
mode,
|
|
16975
|
-
yoloMode: context.yoloMode,
|
|
16976
|
-
riskClass: metadata.riskClass,
|
|
16977
|
-
permissionScope: metadata.permissionScope,
|
|
16978
|
-
requiresPermission: requiresConfirmation
|
|
16979
|
-
};
|
|
16980
|
-
}
|
|
16981
|
-
if (context.confirmationPolicy === "deny" || mode === "subagent") {
|
|
16982
|
-
const reason = mode === "subagent" ? "subagent cannot request interactive permission" : "permission confirmation is unavailable";
|
|
16983
|
-
return {
|
|
16984
|
-
disposition: "deny",
|
|
16985
|
-
allowed: false,
|
|
16986
|
-
reason,
|
|
16987
|
-
policyReason: reason,
|
|
16988
|
-
mode,
|
|
16989
|
-
yoloMode: context.yoloMode,
|
|
16990
|
-
riskClass: metadata.riskClass,
|
|
16991
|
-
permissionScope: metadata.permissionScope,
|
|
16992
|
-
requiresPermission: true
|
|
16993
|
-
};
|
|
16994
|
-
}
|
|
16995
|
-
return {
|
|
16996
|
-
disposition: "confirm",
|
|
16997
|
-
allowed: false,
|
|
16998
|
-
reason: "permission confirmation required",
|
|
16999
|
-
policyReason: "permission confirmation required",
|
|
17000
|
-
mode,
|
|
17001
|
-
yoloMode: context.yoloMode,
|
|
17002
|
-
riskClass: metadata.riskClass,
|
|
17003
|
-
permissionScope: metadata.permissionScope,
|
|
17004
|
-
requiresPermission: true
|
|
17005
|
-
};
|
|
17006
|
-
}
|
|
17007
|
-
function blockedResult(toolName, decision) {
|
|
17008
|
-
return {
|
|
17009
|
-
content: [
|
|
17010
|
-
{
|
|
17011
|
-
type: "text",
|
|
17012
|
-
text: `Blocked ${toolName}: ${decision.reason ?? decision.policyReason ?? "permission denied"}`
|
|
17013
|
-
}
|
|
17014
|
-
],
|
|
17015
|
-
details: { permissionDecision: decision },
|
|
17016
|
-
isError: true
|
|
17017
|
-
};
|
|
17018
|
-
}
|
|
17019
|
-
function mergePermissionDetails(details, decision) {
|
|
17020
|
-
if (details && typeof details === "object" && !Array.isArray(details)) {
|
|
17021
|
-
const record = details;
|
|
17022
|
-
if (record.permissionDecision) {
|
|
17023
|
-
return { ...record, capabilityPolicyDecision: decision };
|
|
17024
|
-
}
|
|
17025
|
-
return { ...record, permissionDecision: decision };
|
|
17026
|
-
}
|
|
17027
|
-
return { permissionDecision: decision };
|
|
17028
|
-
}
|
|
17029
|
-
function createPolicyEnforcedTool(tool, options = {}) {
|
|
17030
|
-
const marker = tool[POLICY_ENFORCED];
|
|
17031
|
-
const intactWrapper = !!marker && marker.wrapperExecute === tool.execute;
|
|
17032
|
-
if (intactWrapper && marker.getContext === options.getContext && marker.permissionProvider === options.permissionProvider) {
|
|
17033
|
-
return tool;
|
|
17034
|
-
}
|
|
17035
|
-
const target = intactWrapper ? marker.base : tool;
|
|
17036
|
-
const wrapped = {
|
|
17037
|
-
...target,
|
|
17038
|
-
execute: async (toolCallId, args, signal, onUpdate) => {
|
|
17039
|
-
let decision = evaluateToolPermission(target, options.getContext?.());
|
|
17040
|
-
if (decision.disposition === "confirm") {
|
|
17041
|
-
const approved = await options.permissionProvider?.confirm({ toolName: target.name, args, decision }).catch(() => false);
|
|
17042
|
-
if (!approved) {
|
|
17043
|
-
return blockedResult(target.name, {
|
|
17044
|
-
...decision,
|
|
17045
|
-
disposition: "deny",
|
|
17046
|
-
reason: "permission denied by user",
|
|
17047
|
-
policyReason: "permission denied by user"
|
|
17048
|
-
});
|
|
17049
|
-
}
|
|
17050
|
-
decision = {
|
|
17051
|
-
...decision,
|
|
17052
|
-
disposition: "allow",
|
|
17053
|
-
allowed: true,
|
|
17054
|
-
reason: void 0,
|
|
17055
|
-
policyReason: void 0
|
|
17056
|
-
};
|
|
17057
|
-
}
|
|
17058
|
-
if (!decision.allowed) return blockedResult(target.name, decision);
|
|
17059
|
-
const result = await target.execute(toolCallId, args, signal, onUpdate);
|
|
17060
|
-
return {
|
|
17061
|
-
...result,
|
|
17062
|
-
details: mergePermissionDetails(result.details, decision)
|
|
17063
|
-
};
|
|
17064
|
-
}
|
|
17065
|
-
};
|
|
17066
|
-
wrapped[POLICY_ENFORCED] = {
|
|
17067
|
-
getContext: options.getContext,
|
|
17068
|
-
permissionProvider: options.permissionProvider,
|
|
17069
|
-
wrapperExecute: wrapped.execute,
|
|
17070
|
-
base: target
|
|
17071
|
-
};
|
|
17072
|
-
return wrapped;
|
|
17073
|
-
}
|
|
17074
|
-
function createPolicyEnforcedTools(tools, options = {}) {
|
|
17075
|
-
return tools.map((tool) => createPolicyEnforcedTool(tool, options));
|
|
17076
|
-
}
|
|
17077
|
-
|
|
17078
17265
|
// ../../packages/shared-headless-capabilities/src/system-prompt-tools.ts
|
|
17079
17266
|
function normalizeDescription(description) {
|
|
17080
17267
|
const text = String(description || "").replace(/\s+/g, " ").trim();
|
|
@@ -19494,10 +19681,9 @@ export {
|
|
|
19494
19681
|
supersedeExecutionState,
|
|
19495
19682
|
shouldPreserveExecutionStateForUserText,
|
|
19496
19683
|
BUILTIN_TOOL_CAPABILITY_METADATA,
|
|
19497
|
-
getToolCapabilityMetadata,
|
|
19498
19684
|
isToolAllowedInPlanMode,
|
|
19685
|
+
defaultShellKindForPlatform,
|
|
19499
19686
|
extractPlanTodoItems,
|
|
19500
|
-
isPlanModeSafeCommand,
|
|
19501
19687
|
markCompletedPlanSteps,
|
|
19502
19688
|
createPlanCapability,
|
|
19503
19689
|
modalityForReadFileUnderstandingKind,
|