wave-agent-sdk 1.1.5 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent.d.ts +128 -28
- package/dist/agent.js +201 -49
- package/dist/builtin/index.js +2 -0
- package/dist/builtin/plugins.js +11 -20
- package/dist/builtin/skills/settings.js +7 -20
- package/dist/builtin/skills/wave-daemon.d.ts +1 -0
- package/dist/builtin/skills/wave-daemon.js +194 -0
- package/dist/constants/images.d.ts +26 -0
- package/dist/constants/images.js +26 -0
- package/dist/constants/index.d.ts +16 -0
- package/dist/constants/index.js +16 -0
- package/dist/constants/memory.d.ts +26 -0
- package/dist/constants/memory.js +34 -0
- package/dist/constants/messages.d.ts +11 -0
- package/dist/constants/messages.js +11 -0
- package/dist/constants/plugins.d.ts +8 -0
- package/dist/constants/plugins.js +8 -0
- package/dist/constants/tools.d.ts +1 -0
- package/dist/constants/tools.js +1 -0
- package/dist/core/plugin.d.ts +54 -10
- package/dist/core/plugin.js +137 -23
- package/dist/core/session.d.ts +1 -1
- package/dist/core/session.js +1 -1
- package/dist/exec/catalog.d.ts +140 -0
- package/dist/exec/catalog.js +470 -0
- package/dist/exec/catalogAnnouncement.d.ts +89 -0
- package/dist/exec/catalogAnnouncement.js +293 -0
- package/dist/exec/constants.d.ts +51 -0
- package/dist/exec/constants.js +51 -0
- package/dist/exec/execRuntime.d.ts +55 -0
- package/dist/exec/execRuntime.js +217 -0
- package/dist/exec/workerSource.d.ts +28 -0
- package/dist/exec/workerSource.js +299 -0
- package/dist/host/index.d.ts +23 -0
- package/dist/host/index.js +23 -0
- package/dist/index.d.ts +7 -1
- package/dist/index.js +8 -1
- package/dist/managers/MemoryRuleManager.d.ts +6 -0
- package/dist/managers/MemoryRuleManager.js +12 -0
- package/dist/managers/aiManager.d.ts +35 -25
- package/dist/managers/aiManager.js +204 -202
- package/dist/managers/backgroundTaskManager.js +14 -0
- package/dist/managers/bashModeManager.d.ts +33 -0
- package/dist/managers/bashModeManager.js +110 -0
- package/dist/managers/hookManager.d.ts +18 -0
- package/dist/managers/hookManager.js +37 -3
- package/dist/managers/liveConfigManager.d.ts +33 -0
- package/dist/managers/liveConfigManager.js +106 -11
- package/dist/managers/lspManager.d.ts +9 -0
- package/dist/managers/lspManager.js +47 -18
- package/dist/managers/mcpManager.d.ts +68 -10
- package/dist/managers/mcpManager.js +265 -15
- package/dist/managers/messageManager.d.ts +60 -18
- package/dist/managers/messageManager.js +170 -81
- package/dist/managers/permissionManager.d.ts +69 -0
- package/dist/managers/permissionManager.js +221 -78
- package/dist/managers/planManager.d.ts +9 -0
- package/dist/managers/planManager.js +19 -1
- package/dist/managers/pluginManager.d.ts +46 -2
- package/dist/managers/pluginManager.js +117 -11
- package/dist/managers/pluginScopeManager.d.ts +15 -2
- package/dist/managers/pluginScopeManager.js +20 -1
- package/dist/managers/skillManager.d.ts +50 -0
- package/dist/managers/skillManager.js +166 -12
- package/dist/managers/slashCommandManager.d.ts +10 -0
- package/dist/managers/slashCommandManager.js +44 -31
- package/dist/managers/subagentManager.d.ts +15 -0
- package/dist/managers/subagentManager.js +81 -9
- package/dist/managers/toolManager.d.ts +29 -3
- package/dist/managers/toolManager.js +87 -13
- package/dist/managers/workflowManager.js +6 -0
- package/dist/prompts/autoMemory.d.ts +9 -0
- package/dist/prompts/autoMemory.js +30 -31
- package/dist/prompts/autoMemoryExtraction.d.ts +4 -0
- package/dist/prompts/autoMemoryExtraction.js +8 -111
- package/dist/prompts/index.d.ts +0 -1
- package/dist/prompts/index.js +0 -4
- package/dist/prompts/memoryTypes.d.ts +63 -0
- package/dist/prompts/memoryTypes.js +191 -0
- package/dist/services/GitService.d.ts +7 -0
- package/dist/services/GitService.js +23 -0
- package/dist/services/MarketplaceService.d.ts +101 -17
- package/dist/services/MarketplaceService.js +323 -102
- package/dist/services/artifactContent.d.ts +84 -0
- package/dist/services/artifactContent.js +204 -0
- package/dist/services/artifactSession.d.ts +6 -0
- package/dist/services/artifactSession.js +17 -0
- package/dist/services/autoMemoryService.js +5 -13
- package/dist/services/configurationService.d.ts +92 -9
- package/dist/services/configurationService.js +246 -64
- package/dist/services/contentSummarizer.d.ts +15 -0
- package/dist/services/contentSummarizer.js +45 -0
- package/dist/services/execAvailability.d.ts +9 -0
- package/dist/services/execAvailability.js +32 -0
- package/dist/services/fileWatcher.js +61 -6
- package/dist/services/initializationService.js +21 -17
- package/dist/services/interactionService.d.ts +9 -1
- package/dist/services/interactionService.js +28 -8
- package/dist/services/jsonlHandler.d.ts +98 -0
- package/dist/services/jsonlHandler.js +250 -12
- package/dist/services/memory.d.ts +17 -1
- package/dist/services/memory.js +44 -7
- package/dist/services/officialMarketplaceMirror.d.ts +85 -0
- package/dist/services/officialMarketplaceMirror.js +290 -0
- package/dist/services/pluginLoader.d.ts +12 -4
- package/dist/services/pluginLoader.js +38 -7
- package/dist/services/remoteSettingsService.js +20 -6
- package/dist/services/session.d.ts +74 -0
- package/dist/services/session.js +174 -16
- package/dist/services/sessionEntries.d.ts +2 -0
- package/dist/services/sessionEntries.js +20 -0
- package/dist/services/worktreeHooks.js +6 -1
- package/dist/stdio/index.d.ts +12 -0
- package/dist/stdio/index.js +12 -0
- package/dist/stdio/notificationRouter.d.ts +38 -0
- package/dist/stdio/notificationRouter.js +97 -0
- package/dist/stdio/rpcClient.d.ts +18 -0
- package/dist/stdio/rpcClient.js +10 -0
- package/dist/stdio/stdioAgent.d.ts +229 -0
- package/dist/stdio/stdioAgent.js +360 -0
- package/dist/tools/artifactTool.js +406 -273
- package/dist/tools/bashTool.js +10 -6
- package/dist/tools/editTool.js +6 -3
- package/dist/tools/execTool.d.ts +2 -0
- package/dist/tools/execTool.js +165 -0
- package/dist/tools/exitPlanMode.js +10 -2
- package/dist/tools/grepTool.js +7 -1
- package/dist/tools/readTool.js +30 -2
- package/dist/tools/types.d.ts +34 -8
- package/dist/tools/webFetchTool.js +15 -166
- package/dist/tools/workflowTool.js +40 -8
- package/dist/tools/writeTool.js +6 -3
- package/dist/types/agent.d.ts +24 -1
- package/dist/types/commands.d.ts +7 -0
- package/dist/types/configuration.d.ts +45 -2
- package/dist/types/hooks.d.ts +1 -0
- package/dist/types/hooks.js +19 -0
- package/dist/types/marketplace.d.ts +40 -2
- package/dist/types/mcp.d.ts +42 -0
- package/dist/types/messaging.d.ts +1 -8
- package/dist/types/permissions.d.ts +22 -0
- package/dist/types/permissions.js +17 -0
- package/dist/types/plugins.d.ts +26 -2
- package/dist/types/skills.d.ts +26 -0
- package/dist/utils/bashParser.d.ts +17 -0
- package/dist/utils/bashParser.js +72 -0
- package/dist/utils/bashStructure/bashLexer.d.ts +96 -0
- package/dist/utils/bashStructure/bashLexer.js +676 -0
- package/dist/utils/bashStructure/bashParser.d.ts +144 -0
- package/dist/utils/bashStructure/bashParser.js +606 -0
- package/dist/utils/bashStructure/bashSemantics.d.ts +70 -0
- package/dist/utils/bashStructure/bashSemantics.js +477 -0
- package/dist/utils/bashStructure/index.d.ts +26 -0
- package/dist/utils/bashStructure/index.js +27 -0
- package/dist/utils/bashStructure/types.d.ts +62 -0
- package/dist/utils/bashStructure/types.js +47 -0
- package/dist/utils/constants.d.ts +10 -0
- package/dist/utils/constants.js +10 -0
- package/dist/utils/containerSetup.js +48 -6
- package/dist/utils/convertMessagesForAPI.d.ts +7 -1
- package/dist/utils/convertMessagesForAPI.js +64 -14
- package/dist/utils/fileChangeReminder.d.ts +20 -0
- package/dist/utils/fileChangeReminder.js +153 -0
- package/dist/utils/fileSearch.js +4 -3
- package/dist/utils/fileUtils.d.ts +44 -0
- package/dist/utils/fileUtils.js +118 -0
- package/dist/utils/frontmatterYaml.d.ts +33 -0
- package/dist/utils/frontmatterYaml.js +192 -0
- package/dist/utils/imageBudget.d.ts +85 -0
- package/dist/utils/imageBudget.js +109 -0
- package/dist/utils/imageDimensions.d.ts +83 -0
- package/dist/utils/imageDimensions.js +232 -0
- package/dist/utils/imageProcessor.d.ts +66 -0
- package/dist/utils/imageProcessor.js +84 -0
- package/dist/utils/imageRewrite.d.ts +29 -0
- package/dist/utils/imageRewrite.js +251 -0
- package/dist/utils/markdownParser.d.ts +5 -1
- package/dist/utils/markdownParser.js +9 -51
- package/dist/utils/mcpInstructions.d.ts +61 -0
- package/dist/utils/mcpInstructions.js +126 -0
- package/dist/utils/mcpUtils.d.ts +7 -0
- package/dist/utils/mcpUtils.js +11 -2
- package/dist/utils/memoryAge.d.ts +32 -0
- package/dist/utils/memoryAge.js +47 -0
- package/dist/utils/memoryEntrypoint.d.ts +20 -0
- package/dist/utils/memoryEntrypoint.js +49 -0
- package/dist/utils/memoryIndex.d.ts +30 -0
- package/dist/utils/memoryIndex.js +76 -0
- package/dist/utils/messageOperations.d.ts +6 -20
- package/dist/utils/messageOperations.js +40 -91
- package/dist/utils/nestedMemory.d.ts +22 -0
- package/dist/utils/nestedMemory.js +61 -0
- package/dist/utils/npmTarball.d.ts +19 -0
- package/dist/utils/npmTarball.js +92 -0
- package/dist/utils/pluginSource.d.ts +37 -0
- package/dist/utils/pluginSource.js +73 -0
- package/dist/utils/ripgrep.d.ts +18 -4
- package/dist/utils/ripgrep.js +56 -4
- package/dist/utils/runtimeDeps.d.ts +35 -0
- package/dist/utils/runtimeDeps.js +426 -0
- package/dist/utils/skillParser.js +22 -52
- package/dist/utils/subagentParser.js +48 -45
- package/dist/utils/tokenCalculation.js +0 -8
- package/dist/utils/userSettings.d.ts +90 -0
- package/dist/utils/userSettings.js +291 -0
- package/dist/utils/worktreeUtils.d.ts +2 -1
- package/dist/utils/worktreeUtils.js +64 -34
- package/package.json +12 -4
- package/dist/managers/bangManager.d.ts +0 -26
- package/dist/managers/bangManager.js +0 -78
|
@@ -15,6 +15,8 @@ export interface PermissionDecision {
|
|
|
15
15
|
newPermissionMode?: PermissionMode;
|
|
16
16
|
/** Signal to persist a new allowed rule */
|
|
17
17
|
newPermissionRule?: string;
|
|
18
|
+
/** Signal to add a directory to this session's Safe Zone (not persisted) */
|
|
19
|
+
newAdditionalDirectory?: string;
|
|
18
20
|
}
|
|
19
21
|
/** Callback function for custom permission logic */
|
|
20
22
|
export type PermissionCallback = (context: ToolPermissionContext) => Promise<PermissionDecision>;
|
|
@@ -32,6 +34,12 @@ export interface ToolPermissionContext {
|
|
|
32
34
|
suggestedPrefix?: string;
|
|
33
35
|
/** Whether to hide the persistent permission option (e.g., "Don't ask again") in the UI */
|
|
34
36
|
hidePersistentOption?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Absolute path of the directory holding an out-of-Safe-Zone target, set for
|
|
39
|
+
* Edit/Write when the target lies outside the Safe Zone. Lets the confirmation
|
|
40
|
+
* UI offer adding that directory to the session Safe Zone.
|
|
41
|
+
*/
|
|
42
|
+
outsideSafeZoneDirectory?: string;
|
|
35
43
|
/** The ID of the tool call that triggered this permission request */
|
|
36
44
|
toolCallId?: string;
|
|
37
45
|
/** The content of the plan being exited from */
|
|
@@ -41,6 +49,20 @@ export interface ToolPermissionContext {
|
|
|
41
49
|
}
|
|
42
50
|
/** List of tools that require permission checks in default mode */
|
|
43
51
|
export declare const RESTRICTED_TOOLS: readonly ["Edit", "Bash", "Write", "EnterPlanMode", "ExitPlanMode", "AskUserQuestion", "Artifact"];
|
|
52
|
+
/**
|
|
53
|
+
* Tools that must still reach the user when permission checks are bypassed
|
|
54
|
+
* (`bypassPermissions` mode, or `plan` mode in a session holding the bypass
|
|
55
|
+
* authorization) — aligned with Claude Code's `requiresUserInteraction`:
|
|
56
|
+
* its permission pipeline returns the tool's own ask result before the
|
|
57
|
+
* bypass step can allow it.
|
|
58
|
+
*
|
|
59
|
+
* - `AskUserQuestion`: the tool *is* the question; bypassing it would strand
|
|
60
|
+
* the agent without an answer.
|
|
61
|
+
* - `ExitPlanMode`: leaving plan mode is the user's approval of the plan, so
|
|
62
|
+
* it stays a user decision even in a "don't ask me" session. This is the
|
|
63
|
+
* one remaining gate on plan mode for such sessions (see plan-mode.md).
|
|
64
|
+
*/
|
|
65
|
+
export declare const USER_INTERACTION_REQUIRED_TOOLS: readonly ["AskUserQuestion", "ExitPlanMode"];
|
|
44
66
|
/** Type for restricted tool names */
|
|
45
67
|
export type RestrictedTool = (typeof RESTRICTED_TOOLS)[number];
|
|
46
68
|
export declare const OPERATION_CANCELLED_BY_USER = "Operation cancelled by user";
|
|
@@ -13,4 +13,21 @@ export const RESTRICTED_TOOLS = [
|
|
|
13
13
|
ASK_USER_QUESTION_TOOL_NAME,
|
|
14
14
|
ARTIFACT_TOOL_NAME,
|
|
15
15
|
];
|
|
16
|
+
/**
|
|
17
|
+
* Tools that must still reach the user when permission checks are bypassed
|
|
18
|
+
* (`bypassPermissions` mode, or `plan` mode in a session holding the bypass
|
|
19
|
+
* authorization) — aligned with Claude Code's `requiresUserInteraction`:
|
|
20
|
+
* its permission pipeline returns the tool's own ask result before the
|
|
21
|
+
* bypass step can allow it.
|
|
22
|
+
*
|
|
23
|
+
* - `AskUserQuestion`: the tool *is* the question; bypassing it would strand
|
|
24
|
+
* the agent without an answer.
|
|
25
|
+
* - `ExitPlanMode`: leaving plan mode is the user's approval of the plan, so
|
|
26
|
+
* it stays a user decision even in a "don't ask me" session. This is the
|
|
27
|
+
* one remaining gate on plan mode for such sessions (see plan-mode.md).
|
|
28
|
+
*/
|
|
29
|
+
export const USER_INTERACTION_REQUIRED_TOOLS = [
|
|
30
|
+
ASK_USER_QUESTION_TOOL_NAME,
|
|
31
|
+
EXIT_PLAN_MODE_TOOL_NAME,
|
|
32
|
+
];
|
|
16
33
|
export const OPERATION_CANCELLED_BY_USER = "Operation cancelled by user";
|
package/dist/types/plugins.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { CustomSlashCommand } from "./commands.js";
|
|
2
2
|
import { Skill } from "./skills.js";
|
|
3
3
|
import { LspConfig } from "./lsp.js";
|
|
4
|
-
import { McpConfig } from "./mcp.js";
|
|
4
|
+
import { McpConfig, McpServerConfig } from "./mcp.js";
|
|
5
5
|
import { PartialHookConfiguration } from "./configuration.js";
|
|
6
6
|
import { SubagentConfiguration } from "../utils/subagentParser.js";
|
|
7
7
|
/**
|
|
@@ -10,10 +10,20 @@ import { SubagentConfiguration } from "../utils/subagentParser.js";
|
|
|
10
10
|
export interface PluginManifest {
|
|
11
11
|
name: string;
|
|
12
12
|
description: string;
|
|
13
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Optional: plugins in the Claude Code ecosystem often omit it (spec plugin
|
|
15
|
+
* A-022). Install and load both fall back to `1.0.0`.
|
|
16
|
+
*/
|
|
17
|
+
version?: string;
|
|
14
18
|
author?: {
|
|
15
19
|
name: string;
|
|
16
20
|
};
|
|
21
|
+
/**
|
|
22
|
+
* Inline MCP server declarations, equivalent to a sibling `.mcp.json`
|
|
23
|
+
* (spec plugin A-023). Claude Code also allows a path string or array of
|
|
24
|
+
* paths here; only the object form is supported.
|
|
25
|
+
*/
|
|
26
|
+
mcpServers?: Record<string, McpServerConfig>;
|
|
17
27
|
}
|
|
18
28
|
/**
|
|
19
29
|
* Plugin configuration in AgentOptions or wave.settings.json
|
|
@@ -22,10 +32,24 @@ export interface PluginConfig {
|
|
|
22
32
|
type: "local";
|
|
23
33
|
path: string;
|
|
24
34
|
}
|
|
35
|
+
/** A plugin root that failed to load during the most recent load/reload. */
|
|
36
|
+
export interface PluginLoadFailure {
|
|
37
|
+
path: string;
|
|
38
|
+
error: string;
|
|
39
|
+
}
|
|
40
|
+
/** Result of `Agent.reloadPlugins()` / `PluginManager.reloadAllPlugins()`. */
|
|
41
|
+
export interface PluginReloadResult {
|
|
42
|
+
/** Plugin names loaded after the reload. */
|
|
43
|
+
plugins: string[];
|
|
44
|
+
/** Plugins that could not be loaded; the reload does not roll back. */
|
|
45
|
+
failures: PluginLoadFailure[];
|
|
46
|
+
}
|
|
25
47
|
/**
|
|
26
48
|
* Represents a loaded plugin in the system
|
|
27
49
|
*/
|
|
28
50
|
export interface Plugin extends PluginManifest {
|
|
51
|
+
/** Always resolved on load: a missing manifest version becomes `1.0.0` (A-022). */
|
|
52
|
+
version: string;
|
|
29
53
|
path: string;
|
|
30
54
|
commands: CustomSlashCommand[];
|
|
31
55
|
skills: Skill[];
|
package/dist/types/skills.d.ts
CHANGED
|
@@ -6,6 +6,17 @@ export interface SkillMetadata {
|
|
|
6
6
|
name: string;
|
|
7
7
|
description: string;
|
|
8
8
|
type: "personal" | "project" | "builtin";
|
|
9
|
+
/**
|
|
10
|
+
* Path to the skill **directory** (the folder containing SKILL.md), never
|
|
11
|
+
* to SKILL.md itself. Directory-level contract — all consumers rely on it:
|
|
12
|
+
* - `SkillManager.prepareSkillContent` injects this value for
|
|
13
|
+
* `${WAVE_SKILL_DIR}` / `${CLAUDE_SKILL_DIR}` substitutions and reports it
|
|
14
|
+
* as the "Base directory for this skill";
|
|
15
|
+
* - `SkillManager.deleteSkill` removes this path with `rm(recursive)`.
|
|
16
|
+
* Callers that need the file itself must `join(skillPath, "SKILL.md")`
|
|
17
|
+
* (misreading this as the file path broke the desktop "Edit" action,
|
|
18
|
+
* bug 3466438649392128).
|
|
19
|
+
*/
|
|
9
20
|
skillPath: string;
|
|
10
21
|
allowedTools?: string[];
|
|
11
22
|
context?: "fork";
|
|
@@ -80,6 +91,21 @@ export interface SkillParseOptions {
|
|
|
80
91
|
validateMetadata?: boolean;
|
|
81
92
|
basePath?: string;
|
|
82
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* A skill invocation recorded for context restoration (post-compaction
|
|
96
|
+
* re-injection, spec core/message-compact 场景 4).
|
|
97
|
+
*/
|
|
98
|
+
export interface InvokedSkillRecord {
|
|
99
|
+
skillName: string;
|
|
100
|
+
timestamp: number;
|
|
101
|
+
/**
|
|
102
|
+
* The content the model actually saw when the skill was invoked — directory
|
|
103
|
+
* placeholders already substituted, prefixed with
|
|
104
|
+
* `Base directory for this skill: <path>`. Re-injecting the raw SKILL.md
|
|
105
|
+
* instead would hand the model a literal `${WAVE_SKILL_DIR}`.
|
|
106
|
+
*/
|
|
107
|
+
content?: string;
|
|
108
|
+
}
|
|
83
109
|
export declare const SKILL_DEFAULTS: {
|
|
84
110
|
readonly PERSONAL_SKILLS_DIR: ".wave/skills";
|
|
85
111
|
readonly PROJECT_SKILLS_DIR: ".wave/skills";
|
|
@@ -37,6 +37,23 @@ export declare const DANGEROUS_COMMANDS: string[];
|
|
|
37
37
|
* FR-019.2 through FR-019.7 in tool-permission-system.md.
|
|
38
38
|
*/
|
|
39
39
|
export declare const READ_ONLY_COMMANDS: string[];
|
|
40
|
+
/**
|
|
41
|
+
* Subset of READ_ONLY_COMMANDS whose arguments are file paths (as opposed to
|
|
42
|
+
* strings, names, or flags, e.g. echo, pwd, which, basename). These commands
|
|
43
|
+
* must stay within the Safe Zone: a read-only command accessing a path outside
|
|
44
|
+
* the working directory / additional directories requires confirmation.
|
|
45
|
+
* Aligned with Claude Code's PathCommand list.
|
|
46
|
+
*/
|
|
47
|
+
export declare const PATH_COMMANDS: string[];
|
|
48
|
+
/**
|
|
49
|
+
* Extract file path arguments from a command's argument string.
|
|
50
|
+
* Tokens starting with "-" are treated as flags and skipped; everything after
|
|
51
|
+
* a "--" separator counts as a path. Quoted path arguments are unquoted.
|
|
52
|
+
* Non-path tokens (e.g. a grep pattern) are harmless: they resolve against the
|
|
53
|
+
* working directory and typically do not exist, so isPathInside falls back to
|
|
54
|
+
* the nearest existing parent (the workdir itself) and stays inside.
|
|
55
|
+
*/
|
|
56
|
+
export declare function extractPathArgs(args: string): string[];
|
|
40
57
|
/**
|
|
41
58
|
* Registry of commands and their expected subcommand depth for smart prefix extraction.
|
|
42
59
|
* For example, 'git: 2' means 'git commit' is a valid prefix, but 'git' alone is not.
|
package/dist/utils/bashParser.js
CHANGED
|
@@ -500,6 +500,78 @@ export const READ_ONLY_COMMANDS = [
|
|
|
500
500
|
"bc",
|
|
501
501
|
"sleep",
|
|
502
502
|
];
|
|
503
|
+
/**
|
|
504
|
+
* Subset of READ_ONLY_COMMANDS whose arguments are file paths (as opposed to
|
|
505
|
+
* strings, names, or flags, e.g. echo, pwd, which, basename). These commands
|
|
506
|
+
* must stay within the Safe Zone: a read-only command accessing a path outside
|
|
507
|
+
* the working directory / additional directories requires confirmation.
|
|
508
|
+
* Aligned with Claude Code's PathCommand list.
|
|
509
|
+
*/
|
|
510
|
+
export const PATH_COMMANDS = [
|
|
511
|
+
"ls",
|
|
512
|
+
"find",
|
|
513
|
+
"cat",
|
|
514
|
+
"head",
|
|
515
|
+
"tail",
|
|
516
|
+
"wc",
|
|
517
|
+
"sort",
|
|
518
|
+
"uniq",
|
|
519
|
+
"grep",
|
|
520
|
+
"egrep",
|
|
521
|
+
"fgrep",
|
|
522
|
+
"rg",
|
|
523
|
+
"file",
|
|
524
|
+
"stat",
|
|
525
|
+
"du",
|
|
526
|
+
"df",
|
|
527
|
+
"tree",
|
|
528
|
+
"diff",
|
|
529
|
+
"cmp",
|
|
530
|
+
"md5sum",
|
|
531
|
+
"sha256sum",
|
|
532
|
+
"sha1sum",
|
|
533
|
+
"xxd",
|
|
534
|
+
"od",
|
|
535
|
+
"hexdump",
|
|
536
|
+
"strings",
|
|
537
|
+
"readlink",
|
|
538
|
+
"realpath",
|
|
539
|
+
"jq",
|
|
540
|
+
"yq",
|
|
541
|
+
"cut",
|
|
542
|
+
"paste",
|
|
543
|
+
"column",
|
|
544
|
+
"tr",
|
|
545
|
+
"awk",
|
|
546
|
+
"sed",
|
|
547
|
+
];
|
|
548
|
+
/**
|
|
549
|
+
* Extract file path arguments from a command's argument string.
|
|
550
|
+
* Tokens starting with "-" are treated as flags and skipped; everything after
|
|
551
|
+
* a "--" separator counts as a path. Quoted path arguments are unquoted.
|
|
552
|
+
* Non-path tokens (e.g. a grep pattern) are harmless: they resolve against the
|
|
553
|
+
* working directory and typically do not exist, so isPathInside falls back to
|
|
554
|
+
* the nearest existing parent (the workdir itself) and stays inside.
|
|
555
|
+
*/
|
|
556
|
+
export function extractPathArgs(args) {
|
|
557
|
+
const tokens = args.match(/(?:[^\s"']+|"[^"]*"|'[^']*')+/g) || [];
|
|
558
|
+
const pathArgs = [];
|
|
559
|
+
let afterDoubleDash = false;
|
|
560
|
+
for (const token of tokens) {
|
|
561
|
+
if (afterDoubleDash) {
|
|
562
|
+
pathArgs.push(token);
|
|
563
|
+
continue;
|
|
564
|
+
}
|
|
565
|
+
if (token === "--") {
|
|
566
|
+
afterDoubleDash = true;
|
|
567
|
+
continue;
|
|
568
|
+
}
|
|
569
|
+
if (!token.startsWith("-")) {
|
|
570
|
+
pathArgs.push(token);
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
return pathArgs.map((p) => p.replace(/^['"](.*)['"]$/, "$1"));
|
|
574
|
+
}
|
|
503
575
|
/**
|
|
504
576
|
* Global scope flags for git that only change the target repository or
|
|
505
577
|
* configuration, not the subcommand being run. Shared by TOOL_RULES (smart
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tokenizer for the structure-aware bash parser.
|
|
3
|
+
*
|
|
4
|
+
* Unlike `bashParser.ts`'s text-based heuristics, this tokenizer understands
|
|
5
|
+
* bash quoting so that structural tokens (;, &&, ||, |, &, ( ), do/done/fi…)
|
|
6
|
+
* are only recognized OUTSIDE quotes/substitutions, and words keep enough
|
|
7
|
+
* internal structure for the semantic layer to tell quoted `"$f"` from bare
|
|
8
|
+
* `$f`.
|
|
9
|
+
*
|
|
10
|
+
* Words are tokenized into parts:
|
|
11
|
+
* - lit literal text (single-quoted or plain)
|
|
12
|
+
* - var `$name` / `${name}` expansion (name kept raw, unexpanded)
|
|
13
|
+
* - special `$@` `$*` `$?` `$$` `$!` `$#` `$-` `$0`..`$9`
|
|
14
|
+
* - cmdsub `$(...)` or backtick command substitution (text = inner)
|
|
15
|
+
* - arith `$((...))` — unsupported (dynamic), fail closed
|
|
16
|
+
* - brace `{a,b}` brace expansion — unsupported (dynamic)
|
|
17
|
+
* - process `<(cmd)` / `>(cmd)` process substitution — unsupported
|
|
18
|
+
* Each part records whether it appeared inside double quotes (`q: 'double'`)
|
|
19
|
+
* or bare (`q: 'none'`); single-quoted text is fully literal.
|
|
20
|
+
*
|
|
21
|
+
* The tokenizer FAILS (returns null) on any construct it cannot safely delimit
|
|
22
|
+
* (unterminated quotes / $( / backticks / heredocs). Failures are surfaced by
|
|
23
|
+
* the caller as a fail-closed `unsupported` parse result.
|
|
24
|
+
*/
|
|
25
|
+
export type QuoteCtx = "none" | "single" | "double";
|
|
26
|
+
export type WordPart = {
|
|
27
|
+
t: "lit";
|
|
28
|
+
v: string;
|
|
29
|
+
q: QuoteCtx;
|
|
30
|
+
} | {
|
|
31
|
+
t: "var";
|
|
32
|
+
name: string;
|
|
33
|
+
q: "none" | "double";
|
|
34
|
+
} | {
|
|
35
|
+
t: "special";
|
|
36
|
+
name: string;
|
|
37
|
+
q: "none" | "double";
|
|
38
|
+
} | {
|
|
39
|
+
t: "cmdsub";
|
|
40
|
+
text: string;
|
|
41
|
+
q: "none" | "double";
|
|
42
|
+
} | {
|
|
43
|
+
t: "arith";
|
|
44
|
+
q: "none" | "double";
|
|
45
|
+
} | {
|
|
46
|
+
t: "brace";
|
|
47
|
+
v: string;
|
|
48
|
+
q: "none" | "double";
|
|
49
|
+
} | {
|
|
50
|
+
t: "process";
|
|
51
|
+
text: string;
|
|
52
|
+
q: "none" | "double";
|
|
53
|
+
};
|
|
54
|
+
export interface WordToken {
|
|
55
|
+
t: "word";
|
|
56
|
+
/** Raw word text as written (quotes and $ references preserved). */
|
|
57
|
+
raw: string;
|
|
58
|
+
/** Inner structure for the semantic layer. */
|
|
59
|
+
parts: WordPart[];
|
|
60
|
+
}
|
|
61
|
+
export type OpToken = "&&" | "||" | "|" | "|&" | ";" | ";;" | ";&" | ";;&" | "&" | "(" | ")" | "newline" | "{" | "}";
|
|
62
|
+
export interface OpTok {
|
|
63
|
+
t: "op";
|
|
64
|
+
op: OpToken;
|
|
65
|
+
}
|
|
66
|
+
export interface NlTok {
|
|
67
|
+
t: "nl";
|
|
68
|
+
}
|
|
69
|
+
export type Token = WordToken | OpTok | NlTok | {
|
|
70
|
+
t: "eof";
|
|
71
|
+
};
|
|
72
|
+
/** Raw tokenizer failure: a construct we cannot model → ask (fail closed). */
|
|
73
|
+
export type LexFailureReason = "heredoc" | "unterminated" | "unexpected-char" | "length-limit";
|
|
74
|
+
export declare function isVariableNameStart(ch: string): boolean;
|
|
75
|
+
/**
|
|
76
|
+
* Classify a redirection operator word emitted by the tokenizer.
|
|
77
|
+
* Returns "plain" when the operator still needs a separate following target
|
|
78
|
+
* word (`>`, `2>`, `>>`, `&>`, `>&` …), "folded" when the target is already
|
|
79
|
+
* part of the operator token (`2>&1`, `>&-`), or null when the word is not a
|
|
80
|
+
* redirection operator.
|
|
81
|
+
*
|
|
82
|
+
* The raw word may carry an optional file-descriptor digit prefix (`2>`) and
|
|
83
|
+
* the dup operators `<&`/`>&` may fold their fd/- target when it directly
|
|
84
|
+
* touches the operator (`2>&1` must stay one token so the reconstructed text
|
|
85
|
+
* remains faithful — legacy `2>& 1` text checks would mis-read the target).
|
|
86
|
+
*/
|
|
87
|
+
export declare function redirectOpKind(raw: string): "plain" | "folded" | null;
|
|
88
|
+
/** True when the raw text is a redirection operator (fd prefix allowed). */
|
|
89
|
+
export declare function isRedirectRaw(raw: string): boolean;
|
|
90
|
+
/** Whether a word token is a redirection operator (raw literal, no quoting). */
|
|
91
|
+
export declare function isRedirectWord(w: WordToken): boolean;
|
|
92
|
+
/**
|
|
93
|
+
* Tokenize a bash command string. Returns tokens or null on a lexical
|
|
94
|
+
* construct we deliberately do not support (fail closed).
|
|
95
|
+
*/
|
|
96
|
+
export declare function tokenize(input: string): Token[] | null;
|