sido-askpass 0.2.0 → 0.4.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/sido-askpass.js +42 -26
- package/package.json +4 -5
package/dist/sido-askpass.js
CHANGED
|
@@ -39,7 +39,7 @@ Usage:
|
|
|
39
39
|
sido-askpass install --user|--system
|
|
40
40
|
sido-askpass uninstall --user|--system
|
|
41
41
|
sido-askpass status [--user|--system]
|
|
42
|
-
sido-askpass run <command> [args...]
|
|
42
|
+
sido-askpass run <command> [args...] run <command> with SUDO_ASKPASS set
|
|
43
43
|
sido-askpass --help
|
|
44
44
|
sido-askpass --version`)
|
|
45
45
|
process.exit(0)
|
|
@@ -267,8 +267,19 @@ function do_install(scope ) {
|
|
|
267
267
|
const r = spawnSync('cat', [path], { stdio: ['pipe', 'pipe', 'pipe'] })
|
|
268
268
|
content = r.stdout?.toString() ?? ''
|
|
269
269
|
}
|
|
270
|
-
|
|
271
|
-
|
|
270
|
+
const managed_pattern = /^# sido\nPath askpass .*$/gm
|
|
271
|
+
if (managed_pattern.test(content)) {
|
|
272
|
+
content = content.replace(managed_pattern, `# sido\n${line}`)
|
|
273
|
+
} else if (/^Path askpass /m.test(content)) {
|
|
274
|
+
const old_values = [...content.matchAll(/^Path askpass (.*)$/gm)].map(
|
|
275
|
+
(match) => match[1],
|
|
276
|
+
)
|
|
277
|
+
for (const old_value of old_values) {
|
|
278
|
+
console.error(
|
|
279
|
+
`[sido] warning: replacing Path askpass ${old_value} with "${self_path}"`,
|
|
280
|
+
)
|
|
281
|
+
}
|
|
282
|
+
content = content.replace(/^Path askpass .*$/gm, `# sido\n${line}`)
|
|
272
283
|
} else {
|
|
273
284
|
content += `\n# sido\n${line}\n`
|
|
274
285
|
}
|
|
@@ -358,6 +369,29 @@ function do_status(scope ) {
|
|
|
358
369
|
}
|
|
359
370
|
}
|
|
360
371
|
|
|
372
|
+
// Background `cat` drains the FIFO back to the parent while a blocking command
|
|
373
|
+
// (tmux popup / herdr pane run) fills it. Shell job control reaps the reader on
|
|
374
|
+
// cancel — see AGENTS.md: native fs open() on a FIFO cannot be cancelled from JS,
|
|
375
|
+
// but the shell naturally reaps the background cat on cancel.
|
|
376
|
+
function fifo_drain_script(
|
|
377
|
+
fifo_ref ,
|
|
378
|
+
block_cmd ,
|
|
379
|
+
status_var ,
|
|
380
|
+
) {
|
|
381
|
+
return [
|
|
382
|
+
`cat "${fifo_ref}" &`,
|
|
383
|
+
`reader=$!`,
|
|
384
|
+
block_cmd,
|
|
385
|
+
`${status_var}=$?`,
|
|
386
|
+
`if [ "$${status_var}" -ne 0 ]; then`,
|
|
387
|
+
` kill "$reader" 2>/dev/null`,
|
|
388
|
+
` wait "$reader" 2>/dev/null`,
|
|
389
|
+
` exit "$${status_var}"`,
|
|
390
|
+
`fi`,
|
|
391
|
+
`wait "$reader" 2>/dev/null`,
|
|
392
|
+
].join('\n')
|
|
393
|
+
}
|
|
394
|
+
|
|
361
395
|
// ── tmux ────────────────────────────────────────────────────────────────────
|
|
362
396
|
//
|
|
363
397
|
// tmux command-prompt cannot hide input (-N means numeric-only, not secret).
|
|
@@ -385,20 +419,12 @@ function tmux_prompt() {
|
|
|
385
419
|
process.exit(1)
|
|
386
420
|
}
|
|
387
421
|
|
|
388
|
-
const
|
|
389
|
-
`cat "$1" &`,
|
|
390
|
-
`reader=$!`,
|
|
422
|
+
const block_cmd = [
|
|
391
423
|
`tmux display-popup -E -w 60% -h 5 \\`,
|
|
392
424
|
` -e "SIDO_ASKPASS=$2" -e "SIDO_PROMPT=$3" -e "SIDO_FIFO=$1" \\`,
|
|
393
425
|
` '"$SIDO_ASKPASS" _inner_prompt_receiver "$SIDO_PROMPT" "$SIDO_FIFO"'`,
|
|
394
|
-
`popup_status=$?`,
|
|
395
|
-
`if [ "$popup_status" -ne 0 ]; then`,
|
|
396
|
-
` kill "$reader" 2>/dev/null`,
|
|
397
|
-
` wait "$reader" 2>/dev/null`,
|
|
398
|
-
` exit "$popup_status"`,
|
|
399
|
-
`fi`,
|
|
400
|
-
`wait "$reader" 2>/dev/null`,
|
|
401
426
|
].join('\n')
|
|
427
|
+
const script = fifo_drain_script('$1', block_cmd, 'popup_status')
|
|
402
428
|
|
|
403
429
|
let r
|
|
404
430
|
try {
|
|
@@ -455,18 +481,8 @@ function herdr_prompt() {
|
|
|
455
481
|
process.exit(1)
|
|
456
482
|
}
|
|
457
483
|
|
|
458
|
-
const
|
|
459
|
-
|
|
460
|
-
`reader=$!`,
|
|
461
|
-
`herdr pane run "$1" "$3" _inner_prompt_receiver "$4" "$2"`,
|
|
462
|
-
`run_status=$?`,
|
|
463
|
-
`if [ "$run_status" -ne 0 ]; then`,
|
|
464
|
-
` kill "$reader" 2>/dev/null`,
|
|
465
|
-
` wait "$reader" 2>/dev/null`,
|
|
466
|
-
` exit "$run_status"`,
|
|
467
|
-
`fi`,
|
|
468
|
-
`wait "$reader" 2>/dev/null`,
|
|
469
|
-
].join('\n')
|
|
484
|
+
const block_cmd = `herdr pane run "$1" "$3" _inner_prompt_receiver "$4" "$2"`
|
|
485
|
+
const runner_script = fifo_drain_script('$2', block_cmd, 'run_status')
|
|
470
486
|
|
|
471
487
|
let r
|
|
472
488
|
try {
|
|
@@ -522,7 +538,7 @@ function mac_gui() {
|
|
|
522
538
|
{ stdio: ['inherit', 'pipe', 'inherit'] },
|
|
523
539
|
)
|
|
524
540
|
if (r.status !== 0) process.exit(1)
|
|
525
|
-
process.stdout.write(r.stdout?.toString().
|
|
541
|
+
process.stdout.write(r.stdout?.toString().replace(/\r?\n$/, '') ?? '')
|
|
526
542
|
}
|
|
527
543
|
|
|
528
544
|
function linux_gui() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sido-askpass",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "SUDO_ASKPASS shim for headless agent environments (tmux, Herdr, GUI, TTY)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -31,16 +31,15 @@
|
|
|
31
31
|
"herdr"
|
|
32
32
|
],
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"@types/node": "^24.
|
|
34
|
+
"@types/node": "^24.13.3",
|
|
35
35
|
"amaro": "^1.1.11",
|
|
36
36
|
"prettier": "^3.9.6",
|
|
37
37
|
"typescript": "^7.0.2"
|
|
38
38
|
},
|
|
39
39
|
"scripts": {
|
|
40
40
|
"build": "node scripts/build.ts",
|
|
41
|
-
"
|
|
41
|
+
"test": "node --test test/run.ts",
|
|
42
42
|
"typecheck": "tsc",
|
|
43
|
-
"format": "prettier --write ."
|
|
44
|
-
"format:check": "prettier --check ."
|
|
43
|
+
"format": "prettier --write ."
|
|
45
44
|
}
|
|
46
45
|
}
|