Пульт: выключатель инструментов, помощь с git, память прошлого ответа
Три вещи, которых не хватало по сравнению с пультом DeepShim, — теперь здесь, и DeepShim можно закрывать. 1. Выключатель инструментов. Снят — приставка, дерево папки и напоминание про NEED/LIST/FIND не едут вовсе, круг ровно один: обычное "спросил по этим файлам, получил ответ". Замер на одной задаче: 229 символов вопроса против 1886. В консоли это флаг --no-tools. 2. Помощь с git: ряд всплывает, только если в папке нет репозитория или в .gitignore не хватает строк. Главная - backup/, куда ложатся прежние версии файлов перед записью. Перенесено из пульта DeepShim. 3. "Помнить прошлый ответ": галочка, по которой прошлый ответ уезжает вместе со следующим вопросом. Разговор из нескольких вопросов, которого раньше не было: стенограмма велась внутри одного вопроса и на этом всё. Попутно два дефекта, оба найдены при проверке: - Разбор флагов съедал аргумент после булева флага: "deepwork --apply вопрос" превращался в apply="вопрос", а вопрос пропадал. Молчало, пока булев флаг стоял последним. Та же грабля уже ловилась в ask.mjs; добавлен BOOL_FLAGS. - Блок-запрос вплотную к прозе не распознавался. DeepSeek регулярно пишет "Запрашиваю поиск константы.=== FIND: MAGIC ===" одной строкой, разбор требовал начала строки, и круг уходил впустую. Якорь начала снят, якорь конца оставлен: упоминание формата посреди фразы запросом не считается. От запросов внутри === FILE: === бережёт вырезание этих блоков, а не якорь. Проверено вживую: без инструментов - 229 символов, один круг, верный ответ; с инструментами - FIND распознан, два круга, верный ответ; git - repo:false и пять недостающих строк, после кнопки repo:true и missing пуст; память - "удвой это число" вернуло 80834 против бессмыслицы без галочки. --selftest дополнен двумя случаями на разбор запросов. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
f34e07e807
commit
263ad14810
@@ -38,6 +38,10 @@
|
||||
<div class="row"><input type="text" id="filter" placeholder="фильтр по имени"></div>
|
||||
<div class="scroll" id="tree">загружаю…</div>
|
||||
<div class="row"><button id="none">Снять все</button><span class="muted" id="sel">ничего не выбрано</span></div>
|
||||
<div class="row" id="gitrow" hidden>
|
||||
<button id="gitinit">Инициализировать git</button>
|
||||
<span class="muted" id="gitnote"></span>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<main>
|
||||
@@ -47,8 +51,12 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<button class="primary" id="send">Спросить</button>
|
||||
<label class="muted">шагов <select id="steps" style="width:auto">
|
||||
<label class="muted" title="Разрешить модели самой запрашивать файлы блоками NEED / LIST / FIND. Выключено — один круг и только отмеченные файлы.">
|
||||
<input type="checkbox" id="tools" checked> инструменты</label>
|
||||
<label class="muted" id="stepsbox">шагов <select id="steps" style="width:auto">
|
||||
<option>2</option><option selected>4</option><option>6</option><option>8</option></select></label>
|
||||
<label class="muted" title="Прошлый ответ уедет вместе со следующим вопросом.">
|
||||
<input type="checkbox" id="keep"> помнить прошлый ответ</label>
|
||||
<span class="muted" id="status"></span>
|
||||
</div>
|
||||
<div class="scroll" id="out"></div>
|
||||
@@ -56,6 +64,7 @@
|
||||
|
||||
<script>
|
||||
let files = [];
|
||||
let lastAnswer = ''; // для галочки «помнить прошлый ответ»
|
||||
|
||||
const $ = id => document.getElementById(id);
|
||||
const esc = s => s.replace(/[&<>]/g, c => ({ '&': '&', '<': '<', '>': '>' }[c]));
|
||||
@@ -79,6 +88,12 @@ function count() {
|
||||
}
|
||||
|
||||
$('tree').addEventListener('change', count);
|
||||
|
||||
// Без инструментов круг ровно один — выбор числа шагов теряет смысл.
|
||||
$('tools').addEventListener('change', () => {
|
||||
$('stepsbox').style.opacity = $('tools').checked ? '' : '.4';
|
||||
$('steps').disabled = !$('tools').checked;
|
||||
});
|
||||
$('filter').addEventListener('input', renderTree);
|
||||
$('none').onclick = () => { document.querySelectorAll('#tree input').forEach(i => i.checked = false); count(); };
|
||||
|
||||
@@ -86,6 +101,32 @@ fetch('/api/tree').then(r => r.json()).then(d => {
|
||||
files = d.files; $('root').textContent = d.root; renderTree();
|
||||
});
|
||||
|
||||
// Ряд с git всплывает, только когда он нужен: репозитория нет или в .gitignore
|
||||
// не хватает строк. Главная из них — backup/: туда ложатся прежние версии
|
||||
// файлов перед записью, и однажды они уедут в коммит.
|
||||
async function gitState() {
|
||||
try {
|
||||
const g = await fetch('/api/git').then(r => r.json());
|
||||
const need = !g.repo || g.missing.length;
|
||||
$('gitrow').hidden = !need;
|
||||
if (!need) return;
|
||||
$('gitinit').textContent = g.repo ? 'Дополнить .gitignore' : 'Инициализировать git';
|
||||
$('gitnote').textContent = g.repo ? `не хватает: ${g.missing.join(', ')}`
|
||||
: 'папка не под git';
|
||||
} catch { $('gitrow').hidden = true; }
|
||||
}
|
||||
gitState();
|
||||
|
||||
$('gitinit').onclick = async () => {
|
||||
$('gitinit').disabled = true;
|
||||
const r = await fetch('/api/git/init', { method: 'POST' }).then(x => x.json());
|
||||
$('gitnote').textContent = r.ok
|
||||
? (r.added.length ? `добавлено в .gitignore: ${r.added.join(', ')}` : 'всё уже на месте')
|
||||
: `не вышло: ${r.reason}`;
|
||||
$('gitinit').disabled = false;
|
||||
if (r.ok) setTimeout(gitState, 1200);
|
||||
};
|
||||
|
||||
async function status() {
|
||||
try {
|
||||
const s = await fetch('/api/status').then(r => r.json());
|
||||
@@ -118,7 +159,13 @@ $('send').onclick = async () => {
|
||||
try {
|
||||
const r = await fetch('/api/ask', {
|
||||
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ question, files: chosen(), steps: +$('steps').value }),
|
||||
body: JSON.stringify({
|
||||
question, files: chosen(), steps: +$('steps').value,
|
||||
tools: $('tools').checked,
|
||||
// Галочку между вопросами не сбрасываем: если человек ведёт разговор,
|
||||
// он ведёт его несколькими вопросами подряд.
|
||||
context: $('keep').checked ? lastAnswer : '',
|
||||
}),
|
||||
});
|
||||
const d = await r.json();
|
||||
clearInterval(poll);
|
||||
@@ -131,6 +178,7 @@ $('send').onclick = async () => {
|
||||
};
|
||||
|
||||
function render(d) {
|
||||
lastAnswer = d.answer || '';
|
||||
const steps = d.steps.map(s => `<div class="step">${esc(s)}</div>`).join('');
|
||||
const patches = d.patches.map((p, i) => `
|
||||
<div class="patch">
|
||||
|
||||
Reference in New Issue
Block a user