feat(m6): toFloorEscapeRecord — распознавание escape-одобрения
This commit is contained in:
@@ -189,6 +189,19 @@ export function toApprovalRecord(answer, { question, nowMs = Date.now() } = {})
|
||||
return { type: 'approve_git_operation', command, ts: nowMs };
|
||||
}
|
||||
|
||||
const FLOOR_ESCAPE_RE = /FLOOR-ESCAPE:\s*([^\n]+?)\s*$/;
|
||||
|
||||
/** Перевести ответ AskUser в floor_escape-запись, либо null. Stop-намерения → null. */
|
||||
export function toFloorEscapeRecord(answer, { nowMs = Date.now() } = {}) {
|
||||
if (typeof answer !== 'string') return null;
|
||||
if (isStopAnswer(answer)) return null;
|
||||
const m = FLOOR_ESCAPE_RE.exec(answer);
|
||||
if (!m) return null;
|
||||
const action = m[1].trim();
|
||||
if (!action) return null;
|
||||
return { type: 'floor_escape', action, ts: nowMs };
|
||||
}
|
||||
|
||||
import { signPayload, verifyReceipt, RECEIPT_DOMAINS } from './receipt-sign.mjs';
|
||||
|
||||
/**
|
||||
|
||||
@@ -299,3 +299,17 @@ describe('toApprovalRecord (Stream H Task 6 — schema sync)', () => {
|
||||
expect(toApprovalRecord(42)).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
import { toFloorEscapeRecord } from './askuser-answer-parser.mjs';
|
||||
describe('askuser-answer-parser toFloorEscapeRecord', () => {
|
||||
it('распознаёт FLOOR-ESCAPE токен → запись floor_escape', () => {
|
||||
const r = toFloorEscapeRecord('Разрешаю FLOOR-ESCAPE: bash:git push --force', { nowMs: 5 });
|
||||
expect(r).toEqual({ type: 'floor_escape', action: 'bash:git push --force', ts: 5 });
|
||||
});
|
||||
it('без токена → null', () => {
|
||||
expect(toFloorEscapeRecord('просто да', { nowMs: 5 })).toBe(null);
|
||||
});
|
||||
it('stop-намерение → null', () => {
|
||||
expect(toFloorEscapeRecord('отмена FLOOR-ESCAPE: bash:x', { nowMs: 5 })).toBe(null);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user