@wrongstack/tools 0.273.0 → 0.274.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/index.d.ts CHANGED
@@ -5,7 +5,7 @@ export { replaceTool } from './replace.js';
5
5
  export { globTool } from './glob.js';
6
6
  export { grepTool } from './grep.js';
7
7
  export { bashTool } from './bash.js';
8
- export { execTool } from './exec.js';
8
+ export { configureExecPolicy, execTool, getExecAllowlist, isExecCommandAllowed, resetExecPolicy } from './exec.js';
9
9
  export { fetchTool } from './fetch.js';
10
10
  export { searchTool } from './search.js';
11
11
  export { todoTool } from './todo.js';
@@ -39,6 +39,115 @@ export { OPTIONAL_TOOLS, TIER1_TOOLS, TIER2_TOOLS, TIER3_TOOLS, builtinTools } f
39
39
  export { builtinToolsPack } from './pack.js';
40
40
  import 'node:child_process';
41
41
 
42
+ /**
43
+ * Shell picker for the `bash` tool on Windows.
44
+ *
45
+ * Historically the bash tool always fell back to `cmd.exe` on Windows — a
46
+ * reasonable default for the small set of POSIX-style commands the tool was
47
+ * built around (`echo`, `dir`, `cd`, `set`, etc.). That breaks when the
48
+ * caller emits PowerShell-style commands (e.g. Codex on Windows routinely
49
+ * emits `Get-Content`, `Get-ChildItem`, `Set-Location`, …), which `cmd.exe`
50
+ * rejects with "'Get-Content' is not recognized as an internal or external
51
+ * command, operable program or batch file." This module decides — purely from
52
+ * the command string and a few well-known env vars — which shell should run
53
+ * the command. It returns a tagged value; bash.ts does the actual spawn.
54
+ *
55
+ * The picker never spawns anything itself, so it is safe to unit-test in
56
+ * isolation. Shell *resolution* (finding the actual binary on PATH) lives in
57
+ * `_win32-resolve.ts` and runs at spawn time.
58
+ * @see {@link ../../docs/configuration.md#windows-shell-selection-wrongstackshell} for user-facing documentation of the WRONGSTACK_SHELL env var and auto-detection behavior.
59
+ *
60
+ * Selection precedence (Windows only):
61
+ * 1. `WRONGSTACK_SHELL` env var, if it names a known shell (cmd | powershell
62
+ * | pwsh). This is the override for users who want a fixed shell.
63
+ * 2. Auto-detect: if the command "looks like" PowerShell — i.e. uses cmdlet
64
+ * verb-noun syntax, $-variables, subexpressions, here-strings, etc. —
65
+ * route to PowerShell. Prefers `pwsh` (PowerShell 7+) and falls back to
66
+ * `powershell` (Windows PowerShell 5.1) at spawn time.
67
+ * 3. Default: `cmd.exe` (preserves legacy behavior).
68
+ *
69
+ * On non-Windows the picker is a no-op — bash.ts already routes through
70
+ * `/bin/bash -c`. We return `'cmd'` as a sentinel value that means "the
71
+ * platform default"; bash.ts maps it to the right binary.
72
+ *
73
+ * See docs/configuration.md § "Windows shell selection (WRONGSTACK_SHELL)" for
74
+ * user-facing documentation of the env var and auto-detection behaviour.
75
+ */
76
+ type BashShell = 'cmd' | 'powershell' | 'pwsh';
77
+
78
+ /**
79
+ * Session-shell resolution for Windows.
80
+ *
81
+ * `pickShell` (`_shell-pick.ts`) decides the shell *per command* — it inspects
82
+ * each command string and routes PowerShell-looking work to PowerShell, else
83
+ * `cmd.exe`. That keeps individual commands working, but it means the shell the
84
+ * model is *told* about (the system-prompt Environment block) and the shell that
85
+ * actually runs a given command can disagree, and a plain command like
86
+ * `git status` silently lands in `cmd.exe` while `Get-ChildItem` lands in
87
+ * PowerShell. The model has no stable target to write syntax for.
88
+ *
89
+ * This module resolves ONE shell for the whole session and pins it via the
90
+ * `WRONGSTACK_SHELL` env var. Because `WRONGSTACK_SHELL` is already the top
91
+ * precedence in `pickShell`, pinning it makes every command route to the same
92
+ * shell with zero changes to `bash.ts` — and the system-prompt builder can read
93
+ * the same env var to tell the model exactly which shell + syntax to use.
94
+ *
95
+ * Resolution (Windows only — POSIX has no fixed session shell here; `bash.ts`
96
+ * routes through `/bin/bash -c` and honours an explicit `WRONGSTACK_SHELL` as a
97
+ * binary path):
98
+ * 1. A valid user-set `WRONGSTACK_SHELL` (cmd | powershell | pwsh) wins and is
99
+ * left untouched.
100
+ * 2. Otherwise prefer `pwsh` (PowerShell 7+) when `pwsh.exe` is on PATH.
101
+ * 3. Otherwise `powershell` (Windows PowerShell 5.1).
102
+ * 4. Otherwise `cmd` (only when no PowerShell is installed — effectively never
103
+ * on a real Windows box).
104
+ *
105
+ * @see {@link ../../docs/configuration.md#windows-shell-selection-wrongstackshell}
106
+ */
107
+
108
+ /**
109
+ * Map a raw `WRONGSTACK_SHELL` value (which may carry a `.exe` suffix or odd
110
+ * casing) to a canonical {@link BashShell}, or `undefined` when it is unset /
111
+ * not a known shell. Mirrors the override parsing in `pickShell`.
112
+ */
113
+ declare function normalizeShell(value: string | undefined): BashShell | undefined;
114
+ interface ResolveSessionShellDeps {
115
+ /**
116
+ * Returns true when `bin` (e.g. `'pwsh.exe'`) resolves on PATH. Injectable so
117
+ * the resolver is unit-testable off-Windows; defaults to `resolveWin32Command`
118
+ * (which itself short-circuits to "not found" when `process.platform` is not
119
+ * win32).
120
+ */
121
+ hasBinary?: ((bin: string) => boolean) | undefined;
122
+ }
123
+ /**
124
+ * Pure decision: which single shell should the session use on `platform`?
125
+ * Returns `undefined` on non-win32 (no fixed session shell). Does not mutate
126
+ * anything.
127
+ */
128
+ declare function resolveSessionShell(platform: NodeJS.Platform, env: {
129
+ get(key: string): string | undefined;
130
+ }, deps?: ResolveSessionShellDeps): BashShell | undefined;
131
+ interface EnsureSessionShellOptions {
132
+ /** Env to read/mutate. Defaults to `process.env`. */
133
+ env?: NodeJS.ProcessEnv | undefined;
134
+ /** Platform override (tests). Defaults to `process.platform`. */
135
+ platform?: NodeJS.Platform | undefined;
136
+ /** Binary-presence probe (tests). Forwarded to {@link resolveSessionShell}. */
137
+ hasBinary?: ((bin: string) => boolean) | undefined;
138
+ }
139
+ /**
140
+ * Resolve the session shell and pin it into `WRONGSTACK_SHELL` so the bash tool
141
+ * and the system-prompt builder agree on one stable value. Idempotent:
142
+ *
143
+ * - non-win32 → no-op, returns `undefined`.
144
+ * - a valid user-set `WRONGSTACK_SHELL` → returned as-is, env left untouched.
145
+ * - otherwise → resolves, writes the canonical value into the env, returns it.
146
+ *
147
+ * Call this once at process boot, before the system-prompt builder is built.
148
+ */
149
+ declare function ensureSessionShell(opts?: EnsureSessionShellOptions): BashShell | undefined;
150
+
42
151
  /**
43
152
  * `planTool` — the LLM-callable counterpart to the `/plan` slash command.
44
153
  *
@@ -450,4 +559,4 @@ declare const TOOL_ICON_CONFIG: Record<ToolIconId, ToolIconConfig>;
450
559
  */
451
560
  declare const FALLBACK_ICON: ToolIconId;
452
561
 
453
- export { FALLBACK_ICON, type GlobalProcessStatus, type InstanceInfo, type InstanceListOptions, type PersistentProcessEntry, type PersistentRegistryData, type ProcessGuardianConfig, ProcessRegistryImpl, TOOL_ICON_CONFIG, TOOL_ICON_MAP, type ToolIconConfig, type ToolIconId, createGlobalPsSlashCommand, formatGlobalStatus, formatInstanceList, formatInstanceSummary, getInstanceCount, getPersistentProcessRegistry, getProcessGuardian, getToolIcon, listInstances, planTool, resetPersistentProcessRegistry, startProcessGuardian, stopProcessGuardian };
562
+ export { type BashShell, type EnsureSessionShellOptions, FALLBACK_ICON, type GlobalProcessStatus, type InstanceInfo, type InstanceListOptions, type PersistentProcessEntry, type PersistentRegistryData, type ProcessGuardianConfig, ProcessRegistryImpl, type ResolveSessionShellDeps, TOOL_ICON_CONFIG, TOOL_ICON_MAP, type ToolIconConfig, type ToolIconId, createGlobalPsSlashCommand, ensureSessionShell, formatGlobalStatus, formatInstanceList, formatInstanceSummary, getInstanceCount, getPersistentProcessRegistry, getProcessGuardian, getToolIcon, listInstances, normalizeShell, planTool, resetPersistentProcessRegistry, resolveSessionShell, startProcessGuardian, stopProcessGuardian };