aidp 0.49.14 → 0.49.15
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.
- checksums.yaml +4 -4
- data/lib/aidp/execute/deterministic_unit.rb +13 -14
- data/lib/aidp/harness/test_runner.rb +1 -1
- data/lib/aidp/setup/wizard.rb +1 -1
- data/lib/aidp/shell_executor.rb +22 -4
- data/lib/aidp/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: '0088a7c834709e32224adf25831bfd282f1f9a8019261b9055251699d8b5b99a'
|
|
4
|
+
data.tar.gz: b00f8596f8cc68cc26f13553a1f1e1c37f0e1d3a6fb7b21dc79ebbc704fede23
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: dd15f595a34f2d6258eb0c62d787c0bdc78b18f69d09ea9cf7db26846badede64dc469ff9d3adc9a8a99c13d6bf2b3a6ca794744953883000331b380a7bd1de4
|
|
7
|
+
data.tar.gz: b3d0e0710c139d6a509cc7aaf1b07d205b3c1a35b38c61339fa6b83e3ca5ca14708547a7d0af32cf069841bdc7ded1cb493366ab1f672895056e21452e04dec3
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
require "yaml"
|
|
4
4
|
require_relative "../message_display"
|
|
5
5
|
require_relative "../rescue_logging"
|
|
6
|
+
require_relative "../shell_executor"
|
|
6
7
|
require_relative "../util"
|
|
7
8
|
|
|
8
9
|
module Aidp
|
|
@@ -228,24 +229,22 @@ module Aidp
|
|
|
228
229
|
end
|
|
229
230
|
|
|
230
231
|
def build_default_command_runner
|
|
232
|
+
command_executor = ShellExecutor.new
|
|
231
233
|
lambda do |command, _context|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
cmd = TTY::Command.new(printer: :quiet)
|
|
235
|
-
result = cmd.run(command, chdir: @project_dir)
|
|
236
|
-
|
|
237
|
-
{
|
|
238
|
-
exit_status: result.exit_status,
|
|
239
|
-
stdout: result.out,
|
|
240
|
-
stderr: result.err
|
|
241
|
-
}
|
|
242
|
-
rescue TTY::Command::ExitError => e
|
|
243
|
-
result = e.result
|
|
234
|
+
result = command_executor.run_line(command, chdir: @project_dir)
|
|
244
235
|
{
|
|
245
236
|
exit_status: result.exit_status,
|
|
246
|
-
stdout: result.
|
|
247
|
-
stderr: result.
|
|
237
|
+
stdout: result.stdout,
|
|
238
|
+
stderr: result.stderr
|
|
248
239
|
}
|
|
240
|
+
rescue ArgumentError => e
|
|
241
|
+
# Rejected shell syntax or an unparseable command line (Shellwords
|
|
242
|
+
# raises ArgumentError for unbalanced quotes or NUL bytes)
|
|
243
|
+
{exit_status: 127, stdout: "", stderr: e.message}
|
|
244
|
+
rescue SystemCallError => e
|
|
245
|
+
# Spawn failures: missing binary (ENOENT), non-executable file
|
|
246
|
+
# (EACCES), directory used as command (EISDIR), and similar errnos
|
|
247
|
+
{exit_status: 127, stdout: "", stderr: e.message}
|
|
249
248
|
end
|
|
250
249
|
end
|
|
251
250
|
end
|
|
@@ -301,7 +301,7 @@ module Aidp
|
|
|
301
301
|
def execute_command_line(command)
|
|
302
302
|
result = command_runner.run_line(command, chdir: @project_dir)
|
|
303
303
|
[result.stdout, result.stderr, result]
|
|
304
|
-
rescue ArgumentError,
|
|
304
|
+
rescue ArgumentError, SystemCallError => e
|
|
305
305
|
result = ShellExecutor::Result.new(stdout: "", stderr: e.message, exit_status: 1)
|
|
306
306
|
[result.stdout, result.stderr, result]
|
|
307
307
|
end
|
data/lib/aidp/setup/wizard.rb
CHANGED
|
@@ -650,7 +650,7 @@ module Aidp
|
|
|
650
650
|
q.validate(/\A[a-z0-9_]+\z/i, "Name must be alphanumeric with underscores")
|
|
651
651
|
end
|
|
652
652
|
|
|
653
|
-
command = prompt.ask("
|
|
653
|
+
command = prompt.ask("Command to run (executed without a shell; no &&, ||, |, ;, redirects, or VAR=value prefixes):", required: true)
|
|
654
654
|
|
|
655
655
|
category_choices = [
|
|
656
656
|
["Test (unit, integration, e2e)", :test],
|
data/lib/aidp/shell_executor.rb
CHANGED
|
@@ -86,15 +86,33 @@ module Aidp
|
|
|
86
86
|
argv = Shellwords.split(command.to_s)
|
|
87
87
|
raise ArgumentError, "command must not be blank" if argv.empty?
|
|
88
88
|
|
|
89
|
-
#
|
|
90
|
-
#
|
|
91
|
-
|
|
92
|
-
|
|
89
|
+
# A leading NAME=value token is a shell environment assignment; without
|
|
90
|
+
# a shell it would be treated as the program name and fail to run.
|
|
91
|
+
if argv.first.match?(/\A[A-Za-z_][A-Za-z0-9_]*=/)
|
|
92
|
+
raise ArgumentError,
|
|
93
|
+
"environment variable assignments are not supported; " \
|
|
94
|
+
"prefix the command with env (e.g. env VAR=value command)"
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Operator and redirection tokens signal an intent to use shell
|
|
98
|
+
# features, which are intentionally unsupported here; reject them
|
|
99
|
+
# loudly rather than running them as literal arguments. A leading file
|
|
100
|
+
# descriptor digit (e.g. `2>`) still introduces a shell redirect.
|
|
101
|
+
if argv.any? { |token| %w[&& || ; |].include?(token) || token.match?(/\A\d*[<>&]/) }
|
|
93
102
|
raise ArgumentError,
|
|
94
103
|
"shell operators are not supported in configured commands; " \
|
|
95
104
|
"split into separate commands instead: #{command.inspect}"
|
|
96
105
|
end
|
|
97
106
|
|
|
107
|
+
# A single token that still contains shell metacharacters would be
|
|
108
|
+
# handed to Process.spawn as a lone string, which Ruby routes through
|
|
109
|
+
# sh -c; reject it rather than let the shell interpret it.
|
|
110
|
+
if argv.length == 1 && argv.first.match?(/[*?\[\]{}()<>|;&$\\"'`\r\n~#=]/)
|
|
111
|
+
raise ArgumentError,
|
|
112
|
+
"shell metacharacters in a single-token command are not supported; " \
|
|
113
|
+
"split into program and arguments"
|
|
114
|
+
end
|
|
115
|
+
|
|
98
116
|
stdout, stderr, status = Open3.capture3(*argv, **opts)
|
|
99
117
|
Result.new(stdout: stdout, stderr: stderr, exit_status: status.exitstatus)
|
|
100
118
|
end
|
data/lib/aidp/version.rb
CHANGED