@cydm/pie 2.7.7 → 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 +17 -7
- package/dist/builtin/extensions/todo/index.js +3 -3
- package/dist/chunks/{chunk-W5B3OXHQ.js → chunk-5SP2H5QK.js} +1 -1
- package/dist/chunks/{chunk-IU5L5DED.js → chunk-ABZOXNDK.js} +11 -5
- package/dist/chunks/{chunk-UPGEXDEQ.js → chunk-AX5QEIKP.js} +364 -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 +535 -326
- 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,36 +2053,47 @@ function projectHostContextBlock(block, registry) {
|
|
|
1994
2053
|
};
|
|
1995
2054
|
}
|
|
1996
2055
|
}
|
|
1997
|
-
function
|
|
1998
|
-
|
|
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;
|
|
2056
|
+
function projectionSeparator(projectionText) {
|
|
2057
|
+
return projectionText.endsWith("\n") && !projectionText.endsWith("\n\n") ? "" : "\n\n";
|
|
2004
2058
|
}
|
|
2005
2059
|
function projectHostEnvelopes(messages, registry, onProjection) {
|
|
2006
2060
|
let changed = false;
|
|
2007
2061
|
const next = [];
|
|
2008
2062
|
for (const message of messages) {
|
|
2009
|
-
|
|
2010
|
-
if (!block) {
|
|
2063
|
+
if (message.role !== "user") {
|
|
2011
2064
|
next.push(message);
|
|
2012
2065
|
continue;
|
|
2013
2066
|
}
|
|
2014
|
-
const outcome = projectHostContextBlock(block, registry);
|
|
2015
|
-
onProjection?.(outcome);
|
|
2016
2067
|
const content = message.content;
|
|
2017
|
-
|
|
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);
|
|
2018
2090
|
const first = rest[0];
|
|
2019
2091
|
let projectedContent;
|
|
2020
2092
|
if (first && first.type === "text" && typeof first.text === "string") {
|
|
2021
|
-
const merged = first.text.trim().length > 0 ? `${
|
|
2022
|
-
|
|
2023
|
-
${first.text}` : outcome.text;
|
|
2093
|
+
const merged = first.text.trim().length > 0 ? `${text}${separator}${first.text}` : text;
|
|
2024
2094
|
projectedContent = [{ ...first, text: merged }, ...rest.slice(1)];
|
|
2025
2095
|
} else {
|
|
2026
|
-
projectedContent = [{ type: "text", text
|
|
2096
|
+
projectedContent = [{ type: "text", text }, ...rest];
|
|
2027
2097
|
}
|
|
2028
2098
|
next.push({ ...message, content: projectedContent });
|
|
2029
2099
|
changed = true;
|
|
@@ -8158,7 +8228,10 @@ function withSubagentRunContext(stream, hooks) {
|
|
|
8158
8228
|
${SUBAGENT_FINALIZATION_HINT}` } : context, options);
|
|
8159
8229
|
};
|
|
8160
8230
|
}
|
|
8161
|
-
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 ?? "";
|
|
8162
8235
|
const remoteClosure = /SSE stream (?:aborted|closed before end|ended before response completed)/i.test(message);
|
|
8163
8236
|
const classificationText = message.replace(/econnaborted/ig, "").replace(/SSE stream aborted/ig, "remote stream closed");
|
|
8164
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;
|
|
@@ -8176,6 +8249,13 @@ function cancellableBackoff(ms, signal) {
|
|
|
8176
8249
|
if (signal?.aborted) finish();
|
|
8177
8250
|
});
|
|
8178
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
|
+
}
|
|
8179
8259
|
function withSubagentResponseRecovery(stream, backoffMs = 2e3, onRetry, onActivity, hooks) {
|
|
8180
8260
|
return async (model, context, options) => {
|
|
8181
8261
|
for (let attempt = 0; ; attempt++) {
|
|
@@ -8223,7 +8303,7 @@ function withSubagentResponseRecovery(stream, backoffMs = 2e3, onRetry, onActivi
|
|
|
8223
8303
|
message = terminal;
|
|
8224
8304
|
} catch (error) {
|
|
8225
8305
|
finishUsage?.();
|
|
8226
|
-
if (!options?.signal?.aborted && attempt < 2 &&
|
|
8306
|
+
if (!options?.signal?.aborted && attempt < 2 && isRetryableSubagentFailureFrom(factsOf(error))) {
|
|
8227
8307
|
try {
|
|
8228
8308
|
onRetry?.();
|
|
8229
8309
|
} catch {
|
|
@@ -8234,7 +8314,7 @@ function withSubagentResponseRecovery(stream, backoffMs = 2e3, onRetry, onActivi
|
|
|
8234
8314
|
throw error;
|
|
8235
8315
|
}
|
|
8236
8316
|
if (options?.signal?.aborted) throw new Error("Subagent aborted by parent");
|
|
8237
|
-
if (message.stopReason === "error" && attempt < 2 &&
|
|
8317
|
+
if (message.stopReason === "error" && attempt < 2 && isRetryableSubagentFailureFrom({ errorMessage: message.errorMessage, retryable: message.retryable, replayClass: message.replayClass })) {
|
|
8238
8318
|
try {
|
|
8239
8319
|
onRetry?.();
|
|
8240
8320
|
} catch {
|
|
@@ -8383,8 +8463,16 @@ var PROTECTED_POSIX_PATHS = /* @__PURE__ */ new Set([
|
|
|
8383
8463
|
"/Volumes"
|
|
8384
8464
|
]);
|
|
8385
8465
|
var POWERSHELL_DESTRUCTIVE_PATTERNS = [
|
|
8386
|
-
|
|
8387
|
-
|
|
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" },
|
|
8388
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" },
|
|
8389
8477
|
{ pattern: /\b(Stop-Computer|Restart-Computer)\b/i, warning: "may stop or restart the machine", commandClass: "infra_destructive" },
|
|
8390
8478
|
{ pattern: /(^|[;|&\n])\s*(?:Invoke-Expression|iex)\b/i, warning: "evaluates a dynamically constructed string as code", commandClass: "privilege_escalation" },
|
|
@@ -8409,9 +8497,6 @@ function lastPipelineCommand(command) {
|
|
|
8409
8497
|
const segments = command.split("|").map((part) => part.trim()).filter(Boolean);
|
|
8410
8498
|
return segments[segments.length - 1] || command;
|
|
8411
8499
|
}
|
|
8412
|
-
function classifyBashCommand(command, options) {
|
|
8413
|
-
return classifyShellCommand(command, "bash", options);
|
|
8414
|
-
}
|
|
8415
8500
|
function splitShellSegments(command) {
|
|
8416
8501
|
const segments = [];
|
|
8417
8502
|
let current = "";
|
|
@@ -8593,6 +8678,66 @@ function resolveStaticCwdTarget(target, cwd, root) {
|
|
|
8593
8678
|
if (resolved !== normalizedRoot && !isStrictDescendant(resolved, normalizedRoot)) return void 0;
|
|
8594
8679
|
return resolved;
|
|
8595
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
|
+
}
|
|
8596
8741
|
function isStaticallyScopedRecursiveForceRemove(command, options) {
|
|
8597
8742
|
if (!options?.cwd) return false;
|
|
8598
8743
|
const root = options.sandboxRoot || options.cwd;
|
|
@@ -8634,6 +8779,12 @@ function classifyShellCommand(command, shell = "bash", options) {
|
|
|
8634
8779
|
destructive = true;
|
|
8635
8780
|
}
|
|
8636
8781
|
}
|
|
8782
|
+
const dynamicWarnings = dynamicExecutionWarnings(command);
|
|
8783
|
+
if (dynamicWarnings.length > 0) {
|
|
8784
|
+
warnings.push(...dynamicWarnings);
|
|
8785
|
+
commandClass = "unknown_shell";
|
|
8786
|
+
destructive = true;
|
|
8787
|
+
}
|
|
8637
8788
|
for (const entry of destructivePatterns) {
|
|
8638
8789
|
if (entry.pattern.test(command)) {
|
|
8639
8790
|
warnings.push(entry.warning);
|
|
@@ -8809,7 +8960,8 @@ function wrapBashGuard(tool, plan) {
|
|
|
8809
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.`,
|
|
8810
8961
|
execute: async (toolCallId, params, signal, onUpdate) => {
|
|
8811
8962
|
const command = typeof params?.command === "string" ? params.command : "";
|
|
8812
|
-
const
|
|
8963
|
+
const shell = resolveRequestShellKind(params?.shell);
|
|
8964
|
+
const classification = classifyShellCommand(command, shell);
|
|
8813
8965
|
if (classification.destructive) {
|
|
8814
8966
|
const reason = `destructive shell command blocked for subagent: ${classification.riskWarnings.join("; ")}`;
|
|
8815
8967
|
plan.toolsExcluded.push({ name: tool.name, reason });
|
|
@@ -9425,7 +9577,11 @@ ${DELEGATION_REPORT_INSTRUCTION}`;
|
|
|
9425
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.`);
|
|
9426
9578
|
}
|
|
9427
9579
|
const detail = terminalError ? `: ${terminalError.slice(0, 200)}` : "";
|
|
9428
|
-
|
|
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;
|
|
9429
9585
|
}
|
|
9430
9586
|
let response;
|
|
9431
9587
|
if (!collectedResponse) {
|
|
@@ -9443,6 +9599,7 @@ ${DELEGATION_REPORT_INSTRUCTION}`;
|
|
|
9443
9599
|
}
|
|
9444
9600
|
const durationMs = Date.now() - startTime;
|
|
9445
9601
|
task.status = "completed";
|
|
9602
|
+
task.failure = void 0;
|
|
9446
9603
|
observeDelegationPhase(task.observation, "completed");
|
|
9447
9604
|
task.result = response;
|
|
9448
9605
|
task.details = {
|
|
@@ -9469,6 +9626,12 @@ ${DELEGATION_REPORT_INSTRUCTION}`;
|
|
|
9469
9626
|
observeDelegationPhase(task.observation, timedOut ? "deadline" : signal?.aborted ? "cancelled" : "failed");
|
|
9470
9627
|
phaseProgress(task.observation.phase);
|
|
9471
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
|
+
}
|
|
9472
9635
|
task.report ??= parseDelegationReport(void 0, task.id);
|
|
9473
9636
|
task.parentHandoffRequired = isParentHandoffRequired(task);
|
|
9474
9637
|
task.completedAt = Date.now();
|
|
@@ -9805,7 +9968,7 @@ ${SPAWN_USAGE_HINT}` }],
|
|
|
9805
9968
|
await run(task, toolContext.reportProgress, signal);
|
|
9806
9969
|
if (task.wasRecall || task.mode !== "read" || task.status !== "failed" || !task.error) return;
|
|
9807
9970
|
if (signal?.aborted) return;
|
|
9808
|
-
if (!
|
|
9971
|
+
if (!isRetryableSubagentFailureFrom({ errorMessage: task.error, retryable: task.failure?.retryable, replayClass: task.failure?.replayClass })) return;
|
|
9809
9972
|
observeDelegationPhase(task.observation, "task_replay");
|
|
9810
9973
|
const settleMs = Math.max(0, (deps.transientRetryBackoffMs ?? 2e3) * 10);
|
|
9811
9974
|
toolContext.reportProgress?.({ message: `[${task.name}] Provider/transport failure \u2014 replaying the read task once after ${Math.round(settleMs / 1e3)}s`, increment: 0 });
|
|
@@ -9813,6 +9976,7 @@ ${SPAWN_USAGE_HINT}` }],
|
|
|
9813
9976
|
if (signal.aborted) {
|
|
9814
9977
|
task.status = "cancelled";
|
|
9815
9978
|
task.error = "Subagent cancelled during replay backoff";
|
|
9979
|
+
task.failure = void 0;
|
|
9816
9980
|
observeDelegationPhase(task.observation, "cancelled");
|
|
9817
9981
|
task.completedAt = Date.now();
|
|
9818
9982
|
return;
|
|
@@ -9822,6 +9986,7 @@ ${SPAWN_USAGE_HINT}` }],
|
|
|
9822
9986
|
task.runtimeEvidence = [];
|
|
9823
9987
|
task.reportedEvidence = [];
|
|
9824
9988
|
task.error = void 0;
|
|
9989
|
+
task.failure = void 0;
|
|
9825
9990
|
task.report = void 0;
|
|
9826
9991
|
task.result = void 0;
|
|
9827
9992
|
task.details = void 0;
|
|
@@ -9875,6 +10040,10 @@ ${SPAWN_USAGE_HINT}` }],
|
|
|
9875
10040
|
observation: task.observation,
|
|
9876
10041
|
parentHandoffRequired: task.parentHandoffRequired,
|
|
9877
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,
|
|
9878
10047
|
details: task.details
|
|
9879
10048
|
})),
|
|
9880
10049
|
totalDuration,
|
|
@@ -10532,6 +10701,164 @@ function createAskUserCapability() {
|
|
|
10532
10701
|
};
|
|
10533
10702
|
}
|
|
10534
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
|
+
|
|
10535
10862
|
// ../../packages/shared-headless-capabilities/src/builtin/fs/read.ts
|
|
10536
10863
|
import * as nodePath from "node:path";
|
|
10537
10864
|
|
|
@@ -16935,144 +17262,6 @@ function maybeAdvanceTodoExecutionState(state, signal) {
|
|
|
16935
17262
|
};
|
|
16936
17263
|
}
|
|
16937
17264
|
|
|
16938
|
-
// ../../packages/shared-headless-capabilities/src/policy-enforcer.ts
|
|
16939
|
-
var POLICY_ENFORCED = /* @__PURE__ */ Symbol.for("pie.capabilityPolicy.enforced");
|
|
16940
|
-
function evaluateToolPermission(tool, context = {}) {
|
|
16941
|
-
const mode = context.mode ?? "normal";
|
|
16942
|
-
const metadata = getToolCapabilityMetadata(tool);
|
|
16943
|
-
const base = describeToolPolicyDecision(tool, mode);
|
|
16944
|
-
if (!metadata && mode === "normal") {
|
|
16945
|
-
return {
|
|
16946
|
-
disposition: "allow",
|
|
16947
|
-
allowed: true,
|
|
16948
|
-
reason: "unclassified_tool",
|
|
16949
|
-
policyReason: "unclassified_tool",
|
|
16950
|
-
mode,
|
|
16951
|
-
yoloMode: context.yoloMode
|
|
16952
|
-
};
|
|
16953
|
-
}
|
|
16954
|
-
if (!metadata || !base.allowed) {
|
|
16955
|
-
return {
|
|
16956
|
-
disposition: "deny",
|
|
16957
|
-
allowed: false,
|
|
16958
|
-
reason: base.reason ?? "tool not allowed by runtime policy",
|
|
16959
|
-
policyReason: base.reason ?? "tool not allowed by runtime policy",
|
|
16960
|
-
mode,
|
|
16961
|
-
yoloMode: context.yoloMode,
|
|
16962
|
-
riskClass: metadata?.riskClass,
|
|
16963
|
-
permissionScope: metadata?.permissionScope,
|
|
16964
|
-
requiresPermission: metadata?.requiresPermission
|
|
16965
|
-
};
|
|
16966
|
-
}
|
|
16967
|
-
const requiresConfirmation = Boolean(metadata.highRisk || metadata.requiresPermission);
|
|
16968
|
-
if (!requiresConfirmation || context.yoloMode || context.confirmationPolicy === "allow") {
|
|
16969
|
-
return {
|
|
16970
|
-
disposition: "allow",
|
|
16971
|
-
allowed: true,
|
|
16972
|
-
mode,
|
|
16973
|
-
yoloMode: context.yoloMode,
|
|
16974
|
-
riskClass: metadata.riskClass,
|
|
16975
|
-
permissionScope: metadata.permissionScope,
|
|
16976
|
-
requiresPermission: requiresConfirmation
|
|
16977
|
-
};
|
|
16978
|
-
}
|
|
16979
|
-
if (context.confirmationPolicy === "deny" || mode === "subagent") {
|
|
16980
|
-
const reason = mode === "subagent" ? "subagent cannot request interactive permission" : "permission confirmation is unavailable";
|
|
16981
|
-
return {
|
|
16982
|
-
disposition: "deny",
|
|
16983
|
-
allowed: false,
|
|
16984
|
-
reason,
|
|
16985
|
-
policyReason: reason,
|
|
16986
|
-
mode,
|
|
16987
|
-
yoloMode: context.yoloMode,
|
|
16988
|
-
riskClass: metadata.riskClass,
|
|
16989
|
-
permissionScope: metadata.permissionScope,
|
|
16990
|
-
requiresPermission: true
|
|
16991
|
-
};
|
|
16992
|
-
}
|
|
16993
|
-
return {
|
|
16994
|
-
disposition: "confirm",
|
|
16995
|
-
allowed: false,
|
|
16996
|
-
reason: "permission confirmation required",
|
|
16997
|
-
policyReason: "permission confirmation required",
|
|
16998
|
-
mode,
|
|
16999
|
-
yoloMode: context.yoloMode,
|
|
17000
|
-
riskClass: metadata.riskClass,
|
|
17001
|
-
permissionScope: metadata.permissionScope,
|
|
17002
|
-
requiresPermission: true
|
|
17003
|
-
};
|
|
17004
|
-
}
|
|
17005
|
-
function blockedResult(toolName, decision) {
|
|
17006
|
-
return {
|
|
17007
|
-
content: [
|
|
17008
|
-
{
|
|
17009
|
-
type: "text",
|
|
17010
|
-
text: `Blocked ${toolName}: ${decision.reason ?? decision.policyReason ?? "permission denied"}`
|
|
17011
|
-
}
|
|
17012
|
-
],
|
|
17013
|
-
details: { permissionDecision: decision },
|
|
17014
|
-
isError: true
|
|
17015
|
-
};
|
|
17016
|
-
}
|
|
17017
|
-
function mergePermissionDetails(details, decision) {
|
|
17018
|
-
if (details && typeof details === "object" && !Array.isArray(details)) {
|
|
17019
|
-
const record = details;
|
|
17020
|
-
if (record.permissionDecision) {
|
|
17021
|
-
return { ...record, capabilityPolicyDecision: decision };
|
|
17022
|
-
}
|
|
17023
|
-
return { ...record, permissionDecision: decision };
|
|
17024
|
-
}
|
|
17025
|
-
return { permissionDecision: decision };
|
|
17026
|
-
}
|
|
17027
|
-
function createPolicyEnforcedTool(tool, options = {}) {
|
|
17028
|
-
const marker = tool[POLICY_ENFORCED];
|
|
17029
|
-
const intactWrapper = !!marker && marker.wrapperExecute === tool.execute;
|
|
17030
|
-
if (intactWrapper && marker.getContext === options.getContext && marker.permissionProvider === options.permissionProvider) {
|
|
17031
|
-
return tool;
|
|
17032
|
-
}
|
|
17033
|
-
const target = intactWrapper ? marker.base : tool;
|
|
17034
|
-
const wrapped = {
|
|
17035
|
-
...target,
|
|
17036
|
-
execute: async (toolCallId, args, signal, onUpdate) => {
|
|
17037
|
-
let decision = evaluateToolPermission(target, options.getContext?.());
|
|
17038
|
-
if (decision.disposition === "confirm") {
|
|
17039
|
-
const approved = await options.permissionProvider?.confirm({ toolName: target.name, args, decision }).catch(() => false);
|
|
17040
|
-
if (!approved) {
|
|
17041
|
-
return blockedResult(target.name, {
|
|
17042
|
-
...decision,
|
|
17043
|
-
disposition: "deny",
|
|
17044
|
-
reason: "permission denied by user",
|
|
17045
|
-
policyReason: "permission denied by user"
|
|
17046
|
-
});
|
|
17047
|
-
}
|
|
17048
|
-
decision = {
|
|
17049
|
-
...decision,
|
|
17050
|
-
disposition: "allow",
|
|
17051
|
-
allowed: true,
|
|
17052
|
-
reason: void 0,
|
|
17053
|
-
policyReason: void 0
|
|
17054
|
-
};
|
|
17055
|
-
}
|
|
17056
|
-
if (!decision.allowed) return blockedResult(target.name, decision);
|
|
17057
|
-
const result = await target.execute(toolCallId, args, signal, onUpdate);
|
|
17058
|
-
return {
|
|
17059
|
-
...result,
|
|
17060
|
-
details: mergePermissionDetails(result.details, decision)
|
|
17061
|
-
};
|
|
17062
|
-
}
|
|
17063
|
-
};
|
|
17064
|
-
wrapped[POLICY_ENFORCED] = {
|
|
17065
|
-
getContext: options.getContext,
|
|
17066
|
-
permissionProvider: options.permissionProvider,
|
|
17067
|
-
wrapperExecute: wrapped.execute,
|
|
17068
|
-
base: target
|
|
17069
|
-
};
|
|
17070
|
-
return wrapped;
|
|
17071
|
-
}
|
|
17072
|
-
function createPolicyEnforcedTools(tools, options = {}) {
|
|
17073
|
-
return tools.map((tool) => createPolicyEnforcedTool(tool, options));
|
|
17074
|
-
}
|
|
17075
|
-
|
|
17076
17265
|
// ../../packages/shared-headless-capabilities/src/system-prompt-tools.ts
|
|
17077
17266
|
function normalizeDescription(description) {
|
|
17078
17267
|
const text = String(description || "").replace(/\s+/g, " ").trim();
|
|
@@ -19451,6 +19640,7 @@ export {
|
|
|
19451
19640
|
generateEntryId,
|
|
19452
19641
|
createHostEnvelopeProjectorRegistry,
|
|
19453
19642
|
projectHostEnvelopes,
|
|
19643
|
+
isHostContextBlock,
|
|
19454
19644
|
FileSessionStore,
|
|
19455
19645
|
createSessionManager,
|
|
19456
19646
|
prepareSessionCompaction,
|
|
@@ -19491,10 +19681,9 @@ export {
|
|
|
19491
19681
|
supersedeExecutionState,
|
|
19492
19682
|
shouldPreserveExecutionStateForUserText,
|
|
19493
19683
|
BUILTIN_TOOL_CAPABILITY_METADATA,
|
|
19494
|
-
getToolCapabilityMetadata,
|
|
19495
19684
|
isToolAllowedInPlanMode,
|
|
19685
|
+
defaultShellKindForPlatform,
|
|
19496
19686
|
extractPlanTodoItems,
|
|
19497
|
-
isPlanModeSafeCommand,
|
|
19498
19687
|
markCompletedPlanSteps,
|
|
19499
19688
|
createPlanCapability,
|
|
19500
19689
|
modalityForReadFileUnderstandingKind,
|