wave-agent-sdk 1.0.4 → 1.0.6
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/agent.d.ts +23 -1
- package/dist/agent.js +34 -4
- package/dist/managers/aiManager.d.ts +36 -0
- package/dist/managers/aiManager.js +240 -8
- package/dist/managers/messageManager.d.ts +1 -3
- package/dist/managers/messageManager.js +19 -9
- package/dist/managers/slashCommandManager.js +28 -0
- package/dist/managers/subagentManager.d.ts +0 -2
- package/dist/services/session.js +2 -9
- package/dist/telemetry/instrumentation.d.ts +1 -1
- package/dist/telemetry/instrumentation.js +57 -28
- package/dist/tools/bashTool.js +16 -6
- package/dist/tools/grepTool.js +11 -3
- package/dist/types/index.d.ts +3 -0
- package/dist/types/messaging.d.ts +2 -0
- package/dist/utils/containerSetup.js +0 -3
- package/dist/utils/messageOperations.d.ts +10 -1
- package/dist/utils/messageOperations.js +19 -1
- package/dist/utils/notificationXml.js +5 -0
- package/dist/utils/ripgrep.d.ts +4 -4
- package/dist/utils/ripgrep.js +4 -27
- package/package.json +20 -8
- package/bin/rg +0 -79
- package/dist/managers/forkedAgentManager.d.ts +0 -50
- package/dist/managers/forkedAgentManager.js +0 -130
- package/scripts/install_ripgrep.js +0 -111
- package/scripts/postinstall.js +0 -38
- package/src/agent.ts +0 -1271
- package/src/constants/subagents.ts +0 -4
- package/src/constants/toolLimits.ts +0 -15
- package/src/constants/tools.ts +0 -24
- package/src/core/plugin.ts +0 -237
- package/src/core/session.ts +0 -9
- package/src/index.ts +0 -38
- package/src/managers/MemoryRuleManager.ts +0 -198
- package/src/managers/aiManager.ts +0 -2429
- package/src/managers/backgroundTaskManager.ts +0 -480
- package/src/managers/bangManager.ts +0 -119
- package/src/managers/cronManager.ts +0 -401
- package/src/managers/foregroundTaskManager.ts +0 -30
- package/src/managers/forkedAgentManager.ts +0 -216
- package/src/managers/hookManager.ts +0 -1089
- package/src/managers/liveConfigManager.ts +0 -445
- package/src/managers/lspManager.ts +0 -470
- package/src/managers/mcpManager.ts +0 -1010
- package/src/managers/messageManager.ts +0 -1180
- package/src/managers/messageQueue.ts +0 -157
- package/src/managers/permissionManager.ts +0 -1140
- package/src/managers/planManager.ts +0 -112
- package/src/managers/pluginManager.ts +0 -330
- package/src/managers/pluginScopeManager.ts +0 -124
- package/src/managers/reversionManager.ts +0 -178
- package/src/managers/skillManager.ts +0 -578
- package/src/managers/slashCommandManager.ts +0 -564
- package/src/managers/subagentManager.ts +0 -915
- package/src/managers/toolManager.ts +0 -489
- package/src/managers/workflowManager.ts +0 -493
- package/src/prompts/autoMemory.ts +0 -33
- package/src/prompts/autoMemoryExtraction.ts +0 -146
- package/src/prompts/index.ts +0 -506
- package/src/prompts/planModeReminders.ts +0 -126
- package/src/services/GitService.ts +0 -131
- package/src/services/MarketplaceService.ts +0 -1052
- package/src/services/MemoryRuleService.ts +0 -71
- package/src/services/aiService.ts +0 -919
- package/src/services/authService.ts +0 -565
- package/src/services/autoMemoryService.ts +0 -280
- package/src/services/configurationService.ts +0 -1520
- package/src/services/fileWatcher.ts +0 -319
- package/src/services/hook.ts +0 -348
- package/src/services/initializationService.ts +0 -357
- package/src/services/interactionService.ts +0 -229
- package/src/services/jsonlHandler.ts +0 -295
- package/src/services/memory.ts +0 -234
- package/src/services/pluginLoader.ts +0 -252
- package/src/services/remoteSettingsService.ts +0 -366
- package/src/services/reversionService.ts +0 -122
- package/src/services/session.ts +0 -922
- package/src/services/taskManager.ts +0 -321
- package/src/telemetry/events.ts +0 -65
- package/src/telemetry/instrumentation.ts +0 -499
- package/src/telemetry/sessionTracing.ts +0 -348
- package/src/tools/agentTool.ts +0 -322
- package/src/tools/askUserQuestion.ts +0 -160
- package/src/tools/bashTool.ts +0 -621
- package/src/tools/buildTool.ts +0 -61
- package/src/tools/cronCreateTool.ts +0 -161
- package/src/tools/cronDeleteTool.ts +0 -51
- package/src/tools/cronListTool.ts +0 -47
- package/src/tools/editTool.ts +0 -313
- package/src/tools/enterPlanMode.ts +0 -124
- package/src/tools/enterWorktreeTool.ts +0 -190
- package/src/tools/exitPlanMode.ts +0 -139
- package/src/tools/exitWorktreeTool.ts +0 -236
- package/src/tools/globTool.ts +0 -167
- package/src/tools/grepTool.ts +0 -399
- package/src/tools/lspTool.ts +0 -883
- package/src/tools/readTool.ts +0 -426
- package/src/tools/skillTool.ts +0 -248
- package/src/tools/taskManagementTools.ts +0 -574
- package/src/tools/taskStopTool.ts +0 -78
- package/src/tools/types.ts +0 -137
- package/src/tools/webFetchTool.ts +0 -373
- package/src/tools/workflowTool.ts +0 -205
- package/src/tools/writeTool.ts +0 -267
- package/src/types/agent.ts +0 -128
- package/src/types/auth.ts +0 -19
- package/src/types/commands.ts +0 -30
- package/src/types/config.ts +0 -43
- package/src/types/configuration.ts +0 -168
- package/src/types/core.ts +0 -105
- package/src/types/cron.ts +0 -13
- package/src/types/environment.ts +0 -106
- package/src/types/fileSearch.ts +0 -4
- package/src/types/history.ts +0 -7
- package/src/types/hooks.ts +0 -256
- package/src/types/index.ts +0 -41
- package/src/types/lsp.ts +0 -98
- package/src/types/marketplace.ts +0 -71
- package/src/types/mcp.ts +0 -43
- package/src/types/memoryRule.ts +0 -31
- package/src/types/messaging.ts +0 -114
- package/src/types/permissions.ts +0 -80
- package/src/types/plugins.ts +0 -39
- package/src/types/processes.ts +0 -99
- package/src/types/reversion.ts +0 -29
- package/src/types/session.ts +0 -12
- package/src/types/skills.ts +0 -108
- package/src/types/tasks.ts +0 -13
- package/src/types/telemetry.ts +0 -98
- package/src/types/tools.ts +0 -44
- package/src/types/workflow.ts +0 -6
- package/src/utils/abortUtils.ts +0 -118
- package/src/utils/atomicWrite.ts +0 -61
- package/src/utils/bashParser.ts +0 -899
- package/src/utils/cacheControlUtils.ts +0 -426
- package/src/utils/commandArgumentParser.ts +0 -161
- package/src/utils/commandPathResolver.ts +0 -88
- package/src/utils/configPaths.ts +0 -220
- package/src/utils/configValidator.ts +0 -100
- package/src/utils/constants.ts +0 -39
- package/src/utils/container.ts +0 -92
- package/src/utils/containerSetup.ts +0 -371
- package/src/utils/convertMessagesForAPI.ts +0 -326
- package/src/utils/cronTasks.ts +0 -128
- package/src/utils/cronTasksLock.ts +0 -182
- package/src/utils/cronToHuman.ts +0 -99
- package/src/utils/customCommands.ts +0 -95
- package/src/utils/editUtils.ts +0 -20
- package/src/utils/fileFormat.ts +0 -40
- package/src/utils/fileSearch.ts +0 -151
- package/src/utils/fileUtils.ts +0 -223
- package/src/utils/gitUtils.ts +0 -315
- package/src/utils/globalLogger.ts +0 -128
- package/src/utils/groupMessagesByApiRound.ts +0 -121
- package/src/utils/hookMatcher.ts +0 -176
- package/src/utils/markdownParser.ts +0 -317
- package/src/utils/mcpUtils.ts +0 -138
- package/src/utils/messageOperations.ts +0 -641
- package/src/utils/modelCapabilities.ts +0 -30
- package/src/utils/nameGenerator.ts +0 -99
- package/src/utils/notificationXml.ts +0 -57
- package/src/utils/openaiClient.ts +0 -251
- package/src/utils/parseCronExpression.ts +0 -78
- package/src/utils/path.ts +0 -72
- package/src/utils/pathEncoder.ts +0 -400
- package/src/utils/pathSafety.ts +0 -40
- package/src/utils/promptHistory.ts +0 -168
- package/src/utils/ripgrep.ts +0 -35
- package/src/utils/shellResolver.ts +0 -190
- package/src/utils/skillParser.ts +0 -246
- package/src/utils/stringUtils.ts +0 -156
- package/src/utils/subagentParser.ts +0 -279
- package/src/utils/taskReminder.ts +0 -96
- package/src/utils/tokenCalculation.ts +0 -43
- package/src/utils/tokenEstimate.ts +0 -34
- package/src/utils/toolResultStorage.ts +0 -117
- package/src/utils/worktreeSession.ts +0 -26
- package/src/utils/worktreeUtils.ts +0 -786
- package/src/workflow/budgetTracker.ts +0 -34
- package/src/workflow/concurrencyLimiter.ts +0 -47
- package/src/workflow/journal.ts +0 -95
- package/src/workflow/progressReporter.ts +0 -141
- package/src/workflow/runState.ts +0 -65
- package/src/workflow/scriptRuntime.ts +0 -274
- package/src/workflow/structuredOutput.ts +0 -123
- package/src/workflow/types.ts +0 -101
- package/src/workflow/workflowApis.ts +0 -410
- package/vendor/ripgrep/linux-aarch64/rg +0 -0
- package/vendor/ripgrep/linux-x86_64/rg +0 -0
- package/vendor/ripgrep/macos-aarch64/rg +0 -0
- package/vendor/ripgrep/macos-x86_64/rg +0 -0
- package/vendor/ripgrep/windows-aarch64/rg.exe +0 -0
- package/vendor/ripgrep/windows-x86_64/rg.exe +0 -0
|
@@ -1,280 +0,0 @@
|
|
|
1
|
-
import * as path from "node:path";
|
|
2
|
-
import * as fs from "node:fs/promises";
|
|
3
|
-
import { Container } from "../utils/container.js";
|
|
4
|
-
import { MessageManager } from "../managers/messageManager.js";
|
|
5
|
-
import { AIManager } from "../managers/aiManager.js";
|
|
6
|
-
import { MemoryService } from "./memory.js";
|
|
7
|
-
import { ConfigurationService } from "./configurationService.js";
|
|
8
|
-
import { logger } from "../utils/globalLogger.js";
|
|
9
|
-
import { isPathInside } from "../utils/pathSafety.js";
|
|
10
|
-
import { buildAutoMemoryExtractionPrompt } from "../prompts/autoMemoryExtraction.js";
|
|
11
|
-
import {
|
|
12
|
-
READ_ONLY_COMMANDS,
|
|
13
|
-
splitBashCommand,
|
|
14
|
-
hasWriteRedirections,
|
|
15
|
-
hasCommandSubstitution,
|
|
16
|
-
hasProcessSubstitution,
|
|
17
|
-
hasSedInPlace,
|
|
18
|
-
isDangerousFind,
|
|
19
|
-
} from "../utils/bashParser.js";
|
|
20
|
-
import type { Message } from "../types/index.js";
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Message fed back to the extraction fork when the model requests a tool
|
|
24
|
-
* outside the allowed set (Bash rm, MCP tools, Agent, out-of-dir writes...).
|
|
25
|
-
*/
|
|
26
|
-
const DENIED_TOOL_MESSAGE =
|
|
27
|
-
"This tool call was denied during auto-memory extraction. Available tools: " +
|
|
28
|
-
"Read, Grep, Glob, read-only Bash commands, and Write/Edit inside the " +
|
|
29
|
-
"memory directory only.";
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Service responsible for managing the auto-memory background agent lifecycle.
|
|
33
|
-
* Extracts and updates persistent project-level memory from conversation history.
|
|
34
|
-
*/
|
|
35
|
-
export class AutoMemoryService {
|
|
36
|
-
private lastMemoryMessageId: string | null = null;
|
|
37
|
-
private turnsSinceLastExtraction: number = 0;
|
|
38
|
-
private extractionInProgress: boolean = false;
|
|
39
|
-
private pendingExtraction: Promise<void> | null = null;
|
|
40
|
-
|
|
41
|
-
constructor(private container: Container) {}
|
|
42
|
-
|
|
43
|
-
private get messageManager(): MessageManager {
|
|
44
|
-
return this.container.get<MessageManager>("MessageManager")!;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
private get aiManager(): AIManager {
|
|
48
|
-
return this.container.get<AIManager>("AIManager")!;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
private get memoryService(): MemoryService {
|
|
52
|
-
return this.container.get<MemoryService>("MemoryService")!;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
private get configurationService(): ConfigurationService {
|
|
56
|
-
return this.container.get<ConfigurationService>("ConfigurationService")!;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Called at the end of each conversation turn to trigger auto-memory extraction if needed.
|
|
61
|
-
*/
|
|
62
|
-
async onTurnEnd(workdir: string): Promise<void> {
|
|
63
|
-
if (!this.configurationService.resolveAutoMemoryEnabled()) {
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
this.turnsSinceLastExtraction++;
|
|
68
|
-
|
|
69
|
-
const messages = this.messageManager.getMessages();
|
|
70
|
-
if (messages.length === 0) return;
|
|
71
|
-
|
|
72
|
-
// 1. Check if we should run based on throttling
|
|
73
|
-
const frequency = this.configurationService.resolveAutoMemoryFrequency();
|
|
74
|
-
if (this.turnsSinceLastExtraction < frequency) {
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// 2. Check for mutual exclusion: skip if main agent manually updated memory in this turn
|
|
79
|
-
const memoryDir = this.memoryService.getAutoMemoryDirectory(workdir);
|
|
80
|
-
|
|
81
|
-
// Find messages since last extraction
|
|
82
|
-
let startIndex = 0;
|
|
83
|
-
if (this.lastMemoryMessageId) {
|
|
84
|
-
startIndex =
|
|
85
|
-
messages.findIndex((m) => m.id === this.lastMemoryMessageId) + 1;
|
|
86
|
-
if (startIndex <= 0) startIndex = 0;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const recentMessages = messages.slice(startIndex);
|
|
90
|
-
const hasManualMemoryWrite = recentMessages.some(
|
|
91
|
-
(m) =>
|
|
92
|
-
m.role === "assistant" &&
|
|
93
|
-
m.blocks.some((b) => {
|
|
94
|
-
if (
|
|
95
|
-
b.type === "tool" &&
|
|
96
|
-
(b.name === "Write" || b.name === "Edit") &&
|
|
97
|
-
// Only a successful manual write counts as a manual update. A
|
|
98
|
-
// denied/failed write didn't touch memory, so the extraction fork
|
|
99
|
-
// must still run or the information is lost.
|
|
100
|
-
b.success !== false
|
|
101
|
-
) {
|
|
102
|
-
try {
|
|
103
|
-
const params = b.parameters ? JSON.parse(b.parameters) : null;
|
|
104
|
-
const filePath = params?.file_path || params?.path;
|
|
105
|
-
if (filePath) {
|
|
106
|
-
const absolutePath = path.isAbsolute(filePath)
|
|
107
|
-
? filePath
|
|
108
|
-
: path.resolve(workdir, filePath);
|
|
109
|
-
return isPathInside(absolutePath, memoryDir);
|
|
110
|
-
}
|
|
111
|
-
} catch {
|
|
112
|
-
return false;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
return false;
|
|
116
|
-
}),
|
|
117
|
-
);
|
|
118
|
-
|
|
119
|
-
if (hasManualMemoryWrite) {
|
|
120
|
-
logger.debug(
|
|
121
|
-
"Skipping auto-memory extraction: manual memory write detected in this turn.",
|
|
122
|
-
);
|
|
123
|
-
this.lastMemoryMessageId = messages[messages.length - 1].id || null;
|
|
124
|
-
this.turnsSinceLastExtraction = 0;
|
|
125
|
-
return;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// 3. Concurrency guard: if an extraction is already in flight, skip this
|
|
129
|
-
// turn. turnsSinceLastExtraction is intentionally NOT reset so the next
|
|
130
|
-
// eligible turn retriggers the extraction.
|
|
131
|
-
if (this.extractionInProgress) {
|
|
132
|
-
logger.debug(
|
|
133
|
-
"Skipping auto-memory extraction: another extraction is still in progress.",
|
|
134
|
-
);
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
// 4. Trigger the perfect-fork extraction fire-and-forget. The message
|
|
139
|
-
// snapshot and new-message count are computed now; lastMemoryMessageId
|
|
140
|
-
// advances at trigger time so the next extraction starts from a later
|
|
141
|
-
// window even while this one runs.
|
|
142
|
-
const lastExtractedIndex = this.lastMemoryMessageId
|
|
143
|
-
? messages.findIndex((m) => m.id === this.lastMemoryMessageId)
|
|
144
|
-
: -1;
|
|
145
|
-
const newMessageCount =
|
|
146
|
-
lastExtractedIndex === -1
|
|
147
|
-
? messages.length
|
|
148
|
-
: messages.length - 1 - lastExtractedIndex;
|
|
149
|
-
|
|
150
|
-
this.turnsSinceLastExtraction = 0;
|
|
151
|
-
this.lastMemoryMessageId = messages[messages.length - 1].id || null;
|
|
152
|
-
this.extractionInProgress = true;
|
|
153
|
-
const extraction = this.runExtraction(workdir, messages, newMessageCount)
|
|
154
|
-
.catch((error) => {
|
|
155
|
-
logger.error("Auto-memory extraction failed:", error);
|
|
156
|
-
})
|
|
157
|
-
.finally(() => {
|
|
158
|
-
this.extractionInProgress = false;
|
|
159
|
-
this.pendingExtraction = null;
|
|
160
|
-
});
|
|
161
|
-
this.pendingExtraction = extraction;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Wait for an in-flight extraction to settle. Called from Agent.dispose so
|
|
166
|
-
* the process doesn't exit while the extraction fork is mid-flight.
|
|
167
|
-
*/
|
|
168
|
-
async drain(): Promise<void> {
|
|
169
|
-
await this.pendingExtraction;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
* Initialize and execute the extraction in a perfect fork: same system
|
|
174
|
-
* prompt, tools, model, and message prefix as the main conversation, so the
|
|
175
|
-
* prompt cache is reused. A tool gate confines the fork to read-only
|
|
176
|
-
* inspection and memory-directory writes. Runs in-process; callers treat it
|
|
177
|
-
* as fire-and-forget.
|
|
178
|
-
*/
|
|
179
|
-
private async runExtraction(
|
|
180
|
-
workdir: string,
|
|
181
|
-
messages: Message[],
|
|
182
|
-
newMessageCount: number,
|
|
183
|
-
): Promise<void> {
|
|
184
|
-
const memoryDir = this.memoryService.getAutoMemoryDirectory(workdir);
|
|
185
|
-
|
|
186
|
-
// Ensure memory directory exists before starting
|
|
187
|
-
await this.memoryService.ensureAutoMemoryDirectory(workdir);
|
|
188
|
-
|
|
189
|
-
// Prepare manifest of existing memory files
|
|
190
|
-
let existingMemoriesManifest = "";
|
|
191
|
-
try {
|
|
192
|
-
const files = await fs.readdir(memoryDir);
|
|
193
|
-
existingMemoriesManifest = files
|
|
194
|
-
.filter((f) => f.endsWith(".md"))
|
|
195
|
-
.map((f) => `- ${f}`)
|
|
196
|
-
.join("\n");
|
|
197
|
-
} catch {
|
|
198
|
-
// Ignore if directory doesn't exist yet
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
const prompt = buildAutoMemoryExtractionPrompt(
|
|
202
|
-
newMessageCount,
|
|
203
|
-
existingMemoriesManifest,
|
|
204
|
-
);
|
|
205
|
-
|
|
206
|
-
await this.aiManager.runAutoMemoryFork(
|
|
207
|
-
messages,
|
|
208
|
-
`${prompt}\n\nThe memory directory for this project is: ${memoryDir}`,
|
|
209
|
-
{
|
|
210
|
-
maxTurns: 5, // Limit turns to prevent verification rabbit-holes
|
|
211
|
-
canUseTool: (name, args) =>
|
|
212
|
-
this.isAllowedForkTool(name, args, memoryDir, workdir),
|
|
213
|
-
deniedToolMessage: DENIED_TOOL_MESSAGE,
|
|
214
|
-
},
|
|
215
|
-
);
|
|
216
|
-
|
|
217
|
-
logger.debug("Auto-memory extraction completed.");
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
/**
|
|
221
|
-
* Tool gate for the extraction fork: Read/Grep/Glob are always allowed;
|
|
222
|
-
* Write/Edit only when the target path is inside the memory directory; Bash
|
|
223
|
-
* only for read-only commands (aligned with the permission manager's
|
|
224
|
-
* read-only bash classification). Everything else — Bash rm, MCP tools,
|
|
225
|
-
* Agent, out-of-dir writes — is denied.
|
|
226
|
-
*/
|
|
227
|
-
private isAllowedForkTool(
|
|
228
|
-
name: string,
|
|
229
|
-
args: Record<string, unknown>,
|
|
230
|
-
memoryDir: string,
|
|
231
|
-
workdir: string,
|
|
232
|
-
): boolean {
|
|
233
|
-
if (name === "Read" || name === "Grep" || name === "Glob") {
|
|
234
|
-
return true;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
if (name === "Write" || name === "Edit") {
|
|
238
|
-
const filePath = args.file_path ?? args.path;
|
|
239
|
-
if (typeof filePath !== "string" || !filePath) return false;
|
|
240
|
-
const absolutePath = path.isAbsolute(filePath)
|
|
241
|
-
? filePath
|
|
242
|
-
: path.resolve(workdir, filePath);
|
|
243
|
-
return isPathInside(absolutePath, memoryDir);
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
if (name === "Bash") {
|
|
247
|
-
const command = typeof args.command === "string" ? args.command : "";
|
|
248
|
-
return this.isReadOnlyBashCommand(command);
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
return false;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
/**
|
|
255
|
-
* A bash command is read-only when every part is a READ_ONLY_COMMANDS entry
|
|
256
|
-
* without write redirections, command/process substitution, sed -i, or
|
|
257
|
-
* dangerous find flags. Mirrors PermissionManager.isAutoAllowedPart.
|
|
258
|
-
*/
|
|
259
|
-
private isReadOnlyBashCommand(command: string): boolean {
|
|
260
|
-
if (!command.trim()) return false;
|
|
261
|
-
if (hasWriteRedirections(command)) return false;
|
|
262
|
-
if (hasCommandSubstitution(command)) return false;
|
|
263
|
-
if (hasProcessSubstitution(command)) return false;
|
|
264
|
-
if (hasSedInPlace(command)) return false;
|
|
265
|
-
|
|
266
|
-
const parts = splitBashCommand(command);
|
|
267
|
-
if (parts.length === 0) return false;
|
|
268
|
-
|
|
269
|
-
return parts.every((part) => {
|
|
270
|
-
const trimmed = part.trim();
|
|
271
|
-
if (!trimmed) return true;
|
|
272
|
-
const commandMatch = trimmed.match(/^(\w+)(\s+.*)?$/);
|
|
273
|
-
if (!commandMatch) return false;
|
|
274
|
-
const cmd = commandMatch[1];
|
|
275
|
-
if (!READ_ONLY_COMMANDS.includes(cmd)) return false;
|
|
276
|
-
if (cmd === "find" && isDangerousFind(part)) return false;
|
|
277
|
-
return true;
|
|
278
|
-
});
|
|
279
|
-
}
|
|
280
|
-
}
|