Hide password during login fix automous coding agent config

This commit is contained in:
Raven Scott
2026-04-26 05:30:38 -04:00
parent 5676a9d9b7
commit 42c09ed326
3 changed files with 115 additions and 8 deletions
+10 -2
View File
@@ -68,9 +68,17 @@ function bareAgentDefaultConfig() {
emergency_stop_mutations: false,
autonomous_mode_enabled: false,
autonomous_max_runtime_ms: 1800000,
autonomous_completion_required_checks: ['coreutils-test', 'verify-kernel-seeder-parity', 'verify-man-coverage'],
autonomous_completion_required_checks: [],
autonomous_allow_paths: ['*'],
autonomous_deny_ops: ['delete_path', 'request_host_action', 'emit_host_notification'],
autonomous_deny_ops: [
'delete_path',
'request_host_action',
'emit_host_notification',
'list_verification_scripts',
'run_maintenance_gate',
'run_contract_checks',
'summarize_build_drift'
],
autonomous_active: false,
autonomous_started_at_ms: 0,
autonomous_stop_requested: false,
@@ -1157,8 +1157,6 @@ async function bareAgentDispatchTool(o) {
const maxRuntimeMs = Math.min(Math.max(Math.floor(Number(maxRuntimeMsRaw) || 0), 60000), 7_200_000)
const requiredChecks = Array.isArray(args.required_checks)
? args.required_checks.map((x) => String(x || '').trim()).filter(Boolean)
: Array.isArray(cfg.autonomous_completion_required_checks)
? cfg.autonomous_completion_required_checks.map((x) => String(x || '').trim()).filter(Boolean)
: []
const unknown = requiredChecks.filter((x) => !Object.prototype.hasOwnProperty.call(AUTONOMOUS_CHECK_ALLOW, x))
if (unknown.length) {
@@ -1362,7 +1360,13 @@ async function bareAgentDispatchTool(o) {
const command = typeof args.command === 'string' ? args.command : ''
if ((configRef.current || {}).autonomous_active) {
const cmd = command.trim().toLowerCase()
if (cmd.includes('rm ') || cmd.includes(' git reset') || cmd.includes(' git clean')) {
if (
cmd.includes('rm ') ||
cmd.includes(' git reset') ||
cmd.includes(' git clean') ||
cmd.startsWith('git ') ||
cmd.includes(' git ')
) {
return bareAgentJsonResult({ ok: false, error: 'autonomous_command_denied' })
}
}
+97 -2
View File
@@ -126,12 +126,105 @@ function bareAgentReadStreamLineOnce(stdin) {
})
}
/**
* Read one secret line (masked as *) when raw mode is available.
* Falls back to normal line read when raw mode is unavailable.
* @param {Record<string, unknown>} ctx
* @param {import('stream').Readable} stdin
* @param {import('stream').Writable | undefined} stdout
* @returns {Promise<string>}
*/
function bareAgentReadMaskedLineOnce(ctx, stdin, stdout) {
const ttyIn = /** @type {{ setRawMode?: (v: boolean) => void, isTTY?: boolean }} */ (stdin)
if (!ttyIn || typeof ttyIn.setRawMode !== 'function' || !ttyIn.isTTY) {
return bareAgentReadStreamLineOnce(stdin)
}
return new Promise((resolve, reject) => {
/** @type {string[]} */
const chars = []
let done = false
/** @param {string | Uint8Array | Buffer} chunk */
function onData(chunk) {
if (done) return
let s = ''
if (typeof chunk === 'string') s = chunk
else if (chunk instanceof Uint8Array) s = new TextDecoder().decode(chunk)
else if (
typeof Buffer !== 'undefined' &&
typeof Buffer.isBuffer === 'function' &&
Buffer.isBuffer(chunk)
) {
s = chunk.toString('utf8')
} else s = String(chunk)
for (const ch of s) {
const code = ch.charCodeAt(0)
if (ch === '\r' || ch === '\n') {
finish(true)
return
}
if (ch === '\u0003') {
finish(false, new Error('interrupted'))
return
}
if (ch === '\u007f' || ch === '\b') {
if (chars.length) {
chars.pop()
bareAgentWriteOut(ctx, stdout, '\b \b')
}
continue
}
if (code >= 32 && code !== 127) {
chars.push(ch)
bareAgentWriteOut(ctx, stdout, '*')
}
}
}
/** @param {boolean} ok @param {Error} [err] */
function finish(ok, err) {
if (done) return
done = true
cleanup()
if (ok) resolve(chars.join(''))
else reject(err || new Error('masked_input_failed'))
}
function cleanup() {
stdin.removeListener('data', onData)
stdin.removeListener('end', onEnd)
stdin.removeListener('error', onErr)
try {
ttyIn.setRawMode(false)
} catch {
/* ignore */
}
bareAgentWriteOut(ctx, stdout, '\n')
}
function onEnd() {
finish(true)
}
/** @param {unknown} e */
function onErr(e) {
const msg = e && typeof e === 'object' && 'message' in e ? String(e.message) : String(e)
finish(false, new Error(msg))
}
try {
ttyIn.setRawMode(true)
} catch {
return resolve('')
}
stdin.on('data', onData)
stdin.once('end', onEnd)
stdin.once('error', onErr)
if (typeof stdin.resume === 'function') stdin.resume()
})
}
/**
* Write a prompt and read one line using raw streams (not ctx.readLine / TUI stack).
* @param {Record<string, unknown>} ctx
* @param {string} prompt
* @param {{ mask?: boolean }} [opts]
*/
async function bareAgentPromptSetupLine(ctx, prompt) {
async function bareAgentPromptSetupLine(ctx, prompt, opts) {
const stdin = /** @type {import('stream').Readable | undefined} */ (
ctx.replStdin || ctx.stdin
)
@@ -143,6 +236,7 @@ async function bareAgentPromptSetupLine(ctx, prompt) {
throw new Error('setup: stdin stream unavailable')
}
bareAgentWriteOut(ctx, stdout, '\x1b[?25h\x1b[0m' + prompt)
if (opts && opts.mask) return bareAgentReadMaskedLineOnce(ctx, stdin, stdout)
return bareAgentReadStreamLineOnce(stdin)
}
@@ -381,7 +475,8 @@ async function bareAgentInteractiveSetup(ctx, argv0, paths, config, opts) {
const keyRaw =
(await bareAgentPromptSetupLine(
ctx,
'REST API key (paste; may echo) [leave empty to skip]: '
'REST API key [leave empty to skip]: ',
{ mask: true }
)) || ''
if (keyRaw.trim()) config.rest_api_key = keyRaw.trim()
const modelRaw =