# 📦 @goodandready/dsh-time-machine

<div align="center">

<h3>Автоматические теневые снапшоты, путешествие во времени по кодовой базе и мгновенный откат изменений для DeepSeek Harness</h3>

<p align="center">
  <a href="https://www.npmjs.com/package/@goodandready/dsh-time-machine"><img src="https://img.shields.io/npm/v/@goodandready/dsh-time-machine.svg?style=for-the-badge&color=6366f1&labelColor=1e1b4b" alt="npm version"></a>
  <a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-10b981.svg?style=for-the-badge&color=10b981&labelColor=064e3b" alt="license"></a>
  <a href="https://github.com/topics/dsh-plugin"><img src="https://img.shields.io/badge/DSH-Plugin-8b5cf6.svg?style=for-the-badge&labelColor=2e1065" alt="DSH Plugin"></a>
  <a href="https://nodejs.org"><img src="https://img.shields.io/badge/Node-20%2B-f59e0b.svg?style=for-the-badge&labelColor=451a03" alt="Node version"></a>
</p>

<!-- Обязательная кнопка перехода на витрину всех проектов -->
<p align="center">
  <a href="https://goodandready.app/"><img src="https://img.shields.io/badge/Все_проекты_автора-goodandready.app-ff4500.svg?style=for-the-badge&logo=rocket&logoColor=white&labelColor=1a1a2e" alt="Все проекты автора"></a>
</p>

<p align="center">
  <a href="README.md"><b>🇬🇧 English</b></a> •
  <a href="README.ru.md"><b>🇷🇺 Русский</b></a> •
  <a href="README.zh.md"><b>🇨🇳 中文说明</b></a>
</p>

<table align="center">
  <tr>
    <td align="center">
      ⭐ <strong>Если вам нравится этот плагин, поставьте ему звезду на GitHub</strong> — это покажет мне, что плагин вам полезен, и будет мотивировать меня развивать его дальше.
      <br><br>
      🐛 <strong>Если вы нашли баг или хотите предложить новый функционал</strong>, создайте issue на GitHub на любом языке — я рассмотрю ваше предложение и реализую полезные идеи в одной из следующих версий плагина.
    </td>
  </tr>
</table>

</div>

---

## ⚡ Обзор

**`dsh-time-machine`** предоставляет автоматическую систему безопасности и мгновенного отката для рабочего пространства агентов **DeepSeek Harness**.

Автономные агенты часто выполняют сложные рефакторинги множества файлов, выполняют терминальные команды или устанавливают пакеты. В случае ошибок или поломки кода ручной откат через git может быть затруднён и грозит потерей неотслеживаемых файлов или порчей истории коммитов.

`dsh-time-machine` создаёт легковесные **теневые снапшоты (shadow git snapshots)** в фоновом режиме без изменения пользовательских веток и коммитов, обеспечивая **откат в 1 клик, визуальный просмотр Diff и предложение авто-восстановления при сбоях**.

```mermaid
graph LR
    subgraph AgentAction [Действия агента DSH]
        Agent[🤖 Агент: Правка файлов / Запуск команд] --> Trigger{Хук перед действием}
    end

    subgraph TimeMachine [Ядро dsh-time-machine]
        Trigger --> ShadowGit[Движок теневых Git-снапшотов]
        ShadowGit --> Snapshots[(Хронологическая лента чекпоинтов)]
        Snapshots --> DiffEngine[Калькулятор визуальных Diff]
    end

    subgraph SafetyNet [Безопасность и Web UI]
        DiffEngine --> Sidebar[🕒 Вкладка Time Machine в сайдбаре]
        Snapshots --> Rollback[⏪ Мгновенный откат рабочего каталога]
        Rollback --> CleanState[Восстановленное чистое состояние]
        Trigger -.->|Ошибка команды| AutoHeal[🩹 Предложение авто-отката]
    end

    style AgentAction fill:#1e1e2e,stroke:#89b4fa,stroke-width:2px,color:#cdd6f4
    style TimeMachine fill:#181825,stroke:#cba6f7,stroke-width:2px,color:#cdd6f4
    style SafetyNet fill:#11111b,stroke:#a6e3a1,stroke-width:2px,color:#cdd6f4
```

---

## 🌟 Ключевые возможности

### 1. 🛡️ Легковесные теневые Git-снапшоты
* Фиксирует всё рабочее дерево, индексированные и новые файлы через изолированные shadow-ссылки Git;
* Не создаёт лишних коммитов в пользовательской истории, не переключает активные ветки и не сдвигает указатель `HEAD`;
* Изолирует рабочий индекс `.git/index` от фонового сохранения чекпоинтов через переменную `GIT_INDEX_FILE`;
* Хранит скользящую историю последних $N$ чекпоинтов с понятными метками, сессионной привязкой и метками времени.

### 2. ⏪ Мгновенный безопасный откат (`time_machine_checkpoint_rollback`)
* Возвращает всё рабочее пространство к любому предыдущему состоянию за миллисекунды;
* Не затирает историю веток Git: откат выполняется через безопасный `read-tree` + `checkout-index` + `clean -fd`;
* Может вызываться как программно агентом, так и пользователем через кнопку в интерфейсе.

### 3. 🔍 Визуальный инспектор Diff (`time_machine_diff`)
* Сравнивает текущие файлы рабочего каталога со снапшотом и формирует наглядный пофайловый Diff.

### 4. 🕒 Интерактивная хроника в сайдбаре и настройках (`lib/client.js`)
* Встраивается в боковую панель Web UI DSH и карточку настроек плагинов;
* Показывает список чекпоинтов с кнопками «Откатить», «Сравнить Diff» и «Удалить».

### 5. 🩹 Авто-восстановление при сбоях команд
* Автоматически фиксирует контрольную точку при сбоях выполнения инструментов и команд.

---


### 4. Выборочный откат отдельных файлов и защита staging (добавлено в v0.1.15)
- **Точечное восстановление файла**: Восстановление повреждённого файла из снимка без сброса остального рабочего дерева через агентский инструмент `time_machine_file_rollback` или UI модального окна Diff.
- **Защита пользовательского staging**: Состояние незакоммиченного `git add` (`stagedTreeHash`) фиксируется и защищается от перезаписи.
- **Авто-снапшоты перед вызовом рискованных инструментов**: Снятие контрольных точек перед выполнением команд (`bash`, `execute_command`, `apply_patch` и др.).
- **Интерактивный просмотр Diff**: Двухпанельный просмотр с пофайловой статистикой изменений (+/- строк) и кнопкой мгновенного восстановления.

## 🛠️ Инструменты агента (7 инструментов)

| Имя инструмента | Параметры | Описание |
|---|---|---|
| `time_machine_checkpoint_create` | `label?: string, sessionId?: string` | Создаёт теневой чекпоинт перед рискованными правками |
| `time_machine_checkpoint_list` | `sessionId?: string` | Возвращает список недавних снапшотов от новых к старым |
| `time_machine_checkpoint_rollback` | `id: string, confirm: boolean` | Безопасно откатывает файлы рабочего пространства без изменения HEAD ветки |
| `time_machine_diff` | `from: string, to?: string` | Возвращает пофайловый Diff между текущим состоянием и чекпоинтом |
| `time_machine_checkpoint_delete` | `id: string, confirm: boolean` | Удаляет отдельный чекпоинт и очищает соответствующий Git ref |
| `time_machine_checkpoint_prune` | `sessionId?: string, keep?: number` | Прореживает чекпоинты сессии, сохраняя указанное количество самых свежих |

---

## 📦 Быстрая установка

```bash
dsh plugin --profile web add @goodandready/dsh-time-machine
```

---

## ⚙️ Пример конфигурации (`settings.yaml`)

```yaml
dsh-time-machine:
  autoSnapshotEnabled: true    # Создавать чекпоинты перед изменением файлов
  maxSnapshots: 20             # Максимальное количество чекпоинтов в памяти
  autoHealPrompt: true         # Предлагать откат при падении терминальной команды
```

---

## 📋 История версий (Release Notes)

### v0.1.16 — Усиление безопасности API и дедупликация регистрации сайдбара
* **Security (Gitea #38)**: Функция `isTrustedSettingsRequest` переведена на строгий fail-closed режим с обязательной проверкой loopback IP (`127.0.0.1`, `::1`), `sec-fetch-site` (`same-origin`, `none`), соответствия `origin` и `host`, а также авторизационных токенов. На всех 5 мутирующих HTTP-маршрутах (`/create`, `/delete`, `/prune`, `/rollback`, `/rollback-file`) внедрено требование метода `POST` с возвратом `405 Method Not Allowed`, а на маршрутах чтения (`/snapshots`, `/diff`) — требование `GET`.
* **Fixed (GitHub #2)**: Устранена ошибка дублирующей регистрации вкладки (`tab kind "time-machine" is already registered`) в DSH >= 0.1.6-alpha.1 при одновременной доступности нативного `sidebarRightTabs` и `betterSidebar`; внедрен общий маркер дедупликации с приоритетом нативного сайдбара ядра и безопасным подавлением ошибок.

### v0.1.15 — Селективный откат файлов, изоляция staging и модальное окно Diff
* **Added in v0.1.15**: Поддержка точечного отката отдельного файла (`time_machine_file_rollback` инструмент и `/rollback-file` маршрут) без сброса остального рабочего дерева.
* **Added in v0.1.15**: Изоляция staging area пользователя через `stagedTreeHash`, гарантирующая сохранность подготовленных файлов при создании чекпоинтов и откате.
* **Added in v0.1.15**: Интерактивный список файлов в модальном окне Diff с отображением статистики изменений и предпросмотром патча.
* **Added in v0.1.15**: Автоматическое снятие чекпоинтов перед вызовом потенциально опасных инструментов (`auto:pre-tool:<tool>`).
* **Changed in v0.1.15**: Строгое следование стандарту локализации DSH (чистый бандл `en`/`zh`, русская локализация ведётся через репозиторий `goodandready/dsh-russian-lang`).

### v0.1.14 — Редизайн в стиле dsh-clinebot, CSRF-защита и повышение стабильности
* **Added in v0.1.14**: Полное визуальное приведение интерфейса к эталонному стандарту дизайн-токенов `dsh-clinebot`: нативная поддержка темной/светлой темы через переменные `--dsw-alias-*`, акцентные (`.tm-btn-primary`) и деструктивные (`.tm-btn-danger`) кнопки, бейджи статуса в карточке настроек и таблице чекпоинтов, современное модальное окно просмотра diff с размытием фона.
* **Security in v0.1.14**: Внедрена CSRF-защита мутирующих HTTP-маршрутов (`create`, `delete`, `rollback`, `prune`) через валидацию заголовка `Sec-Fetch-Site` (`isTrustedSettingsRequest`).
* **Fixed in v0.1.14**: Автоматическая очистка сиротских индексов Git (`cleanupOrphanedIndices`) подключена к инициализации плагина; добавлено создание аварийных чекпоинтов при ошибках (`autoHealPrompt`) в шину legacy events fallback.

### v0.1.13 — Устранение fallback settings.section и безопасный доступ к settingsScope
* **Changed in v0.1.13**: Удалена регистрация запасной строки верхнего уровня `settings.section` из бокового списка настроек DeepSeek Harness Web UI; настройки плагина строго регистрируются внутри сворачиваемой карточки `settings.plugin.item`.
* **Fixed in v0.1.13**: Доступ к сервису настроек переведён на безопасный вызов `ctx.get('settingsScope')` для предотвращения чтения `undefined` через Cordis proxy.

### v0.1.12 — Исправление размера иконки часов на странице Guide нативного сайдбара
* **Fixed in v0.1.12**: Заменена стрелочная функция иконки на полноценный React-компонент `TimeMachineIcon`, корректно обрабатывающий как объект props `{ size, className }`, так и числовой аргумент; добавлены явные inline-стили (`width`, `height`, `flex: none`), устраняющие растягивание иконки часов на карточке Guide.

### v0.1.11 — Поддержка нативного DSH Right Sidebar и legacy BetterSidebar
* **Added in v0.1.11**: Поддержка нативной правой панели DSH (`sidebarRightTabs` + слот `sidebar.right.pane.tab`), появившейся в DSH 0.1.5-alpha.1, включая регистрацию на странице Guide с иконкой.
* **Preserved in v0.1.11**: Полная обратная совместимость с `betterSidebar`; раздельные идентификаторы поверхностей исключают конфликты или двойное монтирование при совместном включении.
* **Added in v0.1.11**: Безопасный откат к карточке настроек плагина при отсутствии обеих боковых панелей в хосте.

### v0.1.10 — Стабильность, динамический CWD, Unified Diff и оптимизация архитектуры
* **Added in v0.1.10**: Динамическое определение рабочей директории (`cwd`): инструменты и REST API автоматически определяют каталог активной сессии либо принимают явный путь.
* **Added in v0.1.10**: Поддержка Unified Diff (`format: "patch" | "stat"`) с лимитом размера (до 256 КБ) и защитой от переполнения контекста.
* **Added in v0.1.10**: Асинхронная очередь мутаций Git, исключающая конфликты блокировок `index.lock` при одновременных запросах.
* **Added in v0.1.10**: Пакетная вычитка ссылок через `git for-each-ref` вместо $O(N)$ отдельных вызовов `git log`, ускоряющая загрузку списка чекпоинтов.
* **Added in v0.1.10**: Дедупликация снапшотов: авто-сохранение пропускается, если дерево файлов не изменилось с момента прошлого чекпоинта.
* **Added in v0.1.10**: Автоматическая очистка сиротских временных индексов `tm_index_*` при запуске плагина.
* **Changed in v0.1.10**: Оптимизирована карточка настроек: удалено дублирование ленты, добавлено указание на вкладку в боковой панели.
* **Changed in v0.1.10**: Полное логирование ошибок через `console.warn` вместо тихого подавления исключений.

### v0.1.9 — Гармонизация шины событий и очистка зависимостей
* **Changed in v0.1.9**: Устранено потенциальное дублирование авто-снапшотов. Нативная шина событий DSH `session/event` теперь имеет приоритет, а legacy `ctx.events` подключается строго как fallback при отсутствии `ctx.on`.
* **Changed in v0.1.9**: Удалена неиспользуемая зависимость `@deepseek-ai/dsh-credentials` из `peerDependencies`.
* **Added in v0.1.9**: Добавлен дизайн-контракт проекта `docs/design/DESIGN.md`.

### v0.1.7 — Безопасность истории веток, изоляция индекса и события DSH
* **Changed in v0.1.7**: Безопасный откат рабочего каталога через `read-tree` + `checkout-index` + `clean -fd`. Устранена критическая проблема переноса `HEAD` ветки на сиротский коммит.
* **Changed in v0.1.7**: Защита пользовательского индекса Git. Чекпоинты создаются с изолированным `GIT_INDEX_FILE`, предотвращая перезапись подготовленных файлов в `.git/index`.
* **Changed in v0.1.7**: Поддержка нативной шины событий DSH `session/event` для автоматических чекпоинтов на `turn/start`, `approval/asked`, `turn/end` и аварийных снапшотов при ошибках.
* **Changed in v0.1.7**: Автоматическое удаление ссылок `refs/dsh-time-machine/...` из Git при вытеснении старых чекпоинтов по лимиту `maxSnapshots`.
* **Changed in v0.1.7**: Корректный расчет Diff напрямую относительно рабочей директории с незакоммиченными изменениями.
* **Changed in v0.1.7**: Соответствие стандартам DSH Plugin Authoring: поля формы настроек разблокированы строго в состоянии `ready`.
* **Added in v0.1.7**: Защита WebServer API от DoS-атак через лимит тела запроса (макс. 1 МБ).
* **Added in v0.1.7**: Полная китайская локализация интерфейса (`zh`).

---

## 📄 Лицензия

MIT © [GooDAnDReaDY](https://github.com/GooDAnDReaDY)