skrepka 0.9.0__tar.gz
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.
- skrepka-0.9.0/.claude-plugin/marketplace.json +13 -0
- skrepka-0.9.0/.claude-plugin/plugin.json +12 -0
- skrepka-0.9.0/.gitignore +35 -0
- skrepka-0.9.0/CHANGELOG.md +34 -0
- skrepka-0.9.0/LICENSE +21 -0
- skrepka-0.9.0/PKG-INFO +81 -0
- skrepka-0.9.0/PRIVACY.md +84 -0
- skrepka-0.9.0/README.en.md +45 -0
- skrepka-0.9.0/README.md +45 -0
- skrepka-0.9.0/SECURITY.md +72 -0
- skrepka-0.9.0/agents/CONTRACT.md +236 -0
- skrepka-0.9.0/docs/FINDINGS.md +63 -0
- skrepka-0.9.0/docs/LIMITATIONS.md +45 -0
- skrepka-0.9.0/docs/PLUGIN.md +58 -0
- skrepka-0.9.0/docs/QUICKSTART.md +146 -0
- skrepka-0.9.0/pyproject.toml +88 -0
- skrepka-0.9.0/skills/skrepka-comments/SKILL.md +95 -0
- skrepka-0.9.0/skills/skrepka-publish/SKILL.md +62 -0
- skrepka-0.9.0/skills/skrepka-suggestions/SKILL.md +57 -0
- skrepka-0.9.0/skills/skrepka-transfer/SKILL.md +78 -0
- skrepka-0.9.0/skills/skrepka-whatsnew/SKILL.md +62 -0
- skrepka-0.9.0/src/skrepka/__init__.py +7 -0
- skrepka-0.9.0/src/skrepka/_engine.py +4663 -0
- skrepka-0.9.0/src/skrepka/cli.py +107 -0
- skrepka-0.9.0/src/skrepka/config.py +359 -0
- skrepka-0.9.0/src/skrepka/privacy.py +369 -0
- skrepka-0.9.0/src/skrepka/safeio.py +224 -0
- skrepka-0.9.0/src/skrepka/setup.py +1121 -0
- skrepka-0.9.0/tests/conftest.py +48 -0
- skrepka-0.9.0/tests/test_cli_dispatch.py +44 -0
- skrepka-0.9.0/tests/test_docx_anchors.py +87 -0
- skrepka-0.9.0/tests/test_gates_and_output.py +103 -0
- skrepka-0.9.0/tests/test_image_token_leak.py +74 -0
- skrepka-0.9.0/tests/test_init_doctor.py +811 -0
- skrepka-0.9.0/tests/test_md_and_merge.py +92 -0
- skrepka-0.9.0/tests/test_privacy.py +331 -0
- skrepka-0.9.0/tests/test_safeio.py +201 -0
- skrepka-0.9.0/tests/test_skill_kernel.py +116 -0
- skrepka-0.9.0/tests/test_style_preserve.py +436 -0
- skrepka-0.9.0/tests/test_sync_anchors.py +1114 -0
- skrepka-0.9.0/tests/test_text_buffer.py +55 -0
- skrepka-0.9.0/tests/test_upload_image_containment.py +114 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "skrepka",
|
|
3
|
+
"owner": {
|
|
4
|
+
"name": "Slava Ufimtsev"
|
|
5
|
+
},
|
|
6
|
+
"plugins": [
|
|
7
|
+
{
|
|
8
|
+
"name": "skrepka",
|
|
9
|
+
"source": "./",
|
|
10
|
+
"description": "Careful collaborative editing of Google Docs for AI agents — read and answer comments, apply anchor-safe text edits, upload/download markdown."
|
|
11
|
+
}
|
|
12
|
+
]
|
|
13
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "skrepka",
|
|
3
|
+
"description": "Careful collaborative editing of Google Docs for AI agents — read and answer comments, apply anchor-safe text edits, upload/download markdown, without destroying comment anchors or styles.",
|
|
4
|
+
"author": {
|
|
5
|
+
"name": "Slava Ufimtsev",
|
|
6
|
+
"url": "https://github.com/slvfmts/skrepka"
|
|
7
|
+
},
|
|
8
|
+
"homepage": "https://github.com/slvfmts/skrepka",
|
|
9
|
+
"repository": "https://github.com/slvfmts/skrepka",
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"keywords": ["google-docs", "markdown", "comments", "editing", "agents"]
|
|
12
|
+
}
|
skrepka-0.9.0/.gitignore
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# credentials & tokens — never commit
|
|
2
|
+
credentials.json
|
|
3
|
+
client_secret_*.json
|
|
4
|
+
token.json
|
|
5
|
+
*.token.json
|
|
6
|
+
.env
|
|
7
|
+
.env.*
|
|
8
|
+
|
|
9
|
+
# skrepka runtime artifacts
|
|
10
|
+
*.gdocs-base.json
|
|
11
|
+
*.gdocs-sync-journal.json
|
|
12
|
+
*.merged.md
|
|
13
|
+
|
|
14
|
+
# python
|
|
15
|
+
__pycache__/
|
|
16
|
+
*.pyc
|
|
17
|
+
*.egg-info/
|
|
18
|
+
dist/
|
|
19
|
+
build/
|
|
20
|
+
.venv/
|
|
21
|
+
venv/
|
|
22
|
+
.pytest_cache/
|
|
23
|
+
.ruff_cache/
|
|
24
|
+
|
|
25
|
+
# maintainer working context — never published (see pyproject sdist allowlist)
|
|
26
|
+
internal/
|
|
27
|
+
|
|
28
|
+
# os / editors
|
|
29
|
+
.DS_Store
|
|
30
|
+
.idea/
|
|
31
|
+
.vscode/
|
|
32
|
+
|
|
33
|
+
# generated diagnostics / media sources
|
|
34
|
+
doctor-report*.json
|
|
35
|
+
*.gif.src/
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
Формат: [Keep a Changelog](https://keepachangelog.com/ru/1.1.0/), версии по [SemVer](https://semver.org/lang/ru/). До 1.0 публичный контракт может меняться.
|
|
4
|
+
|
|
5
|
+
## [Unreleased]
|
|
6
|
+
|
|
7
|
+
## [0.9.0] — 2026-07-30
|
|
8
|
+
|
|
9
|
+
Первый публичный релиз. Предрелизная линия: до 1.0 публичный контракт может меняться.
|
|
10
|
+
|
|
11
|
+
### Основное
|
|
12
|
+
|
|
13
|
+
- Комментарии из CLI: `comments` (чтение с пагинацией), `reply`, `comment`, `suggestions`. Резолв (`resolve` / `reply --resolve`) требует подтверждения человека; агент не резолвит сам.
|
|
14
|
+
- Якорно-безопасные правки текста: `patch` через `replaceAllText` с картой якорей из DOCX-экспорта. Правки, полностью накрывающие якорь живого комментария, отклоняются с подсказкой, как переписать; частичное перекрытие разрешено.
|
|
15
|
+
- Загрузка и выгрузка: `upload` / `update` (markdown → документ) и `download` (документ → markdown). Деструктивное полное обновление документа с комментариями блокируется, пока не подтверждено явно, с автоматическим бэкапом.
|
|
16
|
+
- Мастер настройки: `init` (пошаговая авторизация в Google, свой OAuth-клиент, smoke-тест) и `doctor` (диагностика кредов, токена, scope, включённости API).
|
|
17
|
+
- Управление локальными данными: `logout` (убрать токен), `revoke` (отозвать на стороне Google, server-first) и `forget` (best-effort удаление артефактов).
|
|
18
|
+
- `sync` (markdown → документ, three-way merge): экспериментальный, не входит в поддержанный сценарий 0.9.
|
|
19
|
+
- Навыки для агента: единое дерево `skills/` в открытом формате `SKILL.md` для Claude Code и OpenAI Codex. Сценарии: «отработай комментарии», «выгрузи/залей», «опубликуй», «разбери предложения», «что нового». В каждый навык вшито ядро безопасности из [agents/CONTRACT.md](agents/CONTRACT.md); CI проверяет его байт-равенство. Установка: [docs/PLUGIN.md](docs/PLUGIN.md).
|
|
20
|
+
|
|
21
|
+
### Безопасность
|
|
22
|
+
|
|
23
|
+
- Запрашивается единственный OAuth-scope `.../auth/drive` (избыточный `documents` убран).
|
|
24
|
+
- Все артефакты пишутся через защищённый I/O (`O_NOFOLLOW` + атомарный `rename`): подменённый по предсказуемому пути симлинк/хардлинк не приводит к записи сквозь него.
|
|
25
|
+
- Токен: `0600` в конфиг-директории `0700`; рефреш с урезанным scope не сохраняется.
|
|
26
|
+
- Резолв комментария (`resolve` / `reply --resolve`) и деструктивное обновление с обнаруженной потерей комментариев/именованных диапазонов (`update --acknowledge-loss`) требуют подтверждения в TTY (неинтерактивный обход: `SKREPKA_ASSUME_HUMAN=1`). Гейт срабатывает при наличии комментариев или именованных диапазонов; документ без тех и других полностью перезаписывается без гейта. Команды управления данными `revoke`/`forget` имеют собственный `--yes`. Это кооперативные границы для агента (см. [PRIVACY.md](PRIVACY.md) и [SECURITY.md](SECURITY.md)), а не криптографические гарантии.
|
|
27
|
+
- Картинки в markdown загружаются только из каталога самого `.md` и его подкаталогов. Абсолютный путь, выход через `../` и симлинк за пределы дерева отклоняются: markdown может быть выгрузкой документа, который писали посторонние, и такая ссылка иначе отправила бы в Drive произвольный локальный файл, на время вставки публично читаемый.
|
|
28
|
+
- SVG не загружается: принимаются только растровые форматы. Рендерер SVG открывает ссылки изнутри файла, а песочницы для него в 0.9 нет.
|
|
29
|
+
- Нет сервера, нет телеметрии. См. [PRIVACY.md](PRIVACY.md) и [SECURITY.md](SECURITY.md).
|
|
30
|
+
|
|
31
|
+
### Известные ограничения
|
|
32
|
+
|
|
33
|
+
- Ограничения 0.9 (single-tab, таблицы/сноски только в UI и др.): [docs/LIMITATIONS.md](docs/LIMITATIONS.md).
|
|
34
|
+
- Платформа: Unix. Windows в 0.9 не поддержан.
|
skrepka-0.9.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Slava Ufimtsev
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
skrepka-0.9.0/PKG-INFO
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: skrepka
|
|
3
|
+
Version: 0.9.0
|
|
4
|
+
Summary: Careful collaborative editing for Google Docs: reply to comments and edit text without ghosting anchors and without flattening styles.
|
|
5
|
+
Project-URL: Homepage, https://github.com/slvfmts/skrepka
|
|
6
|
+
Project-URL: Issues, https://github.com/slvfmts/skrepka/issues
|
|
7
|
+
Author: Slava Ufimtsev
|
|
8
|
+
License: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: claude,comments,editing,google-docs,markdown
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Operating System :: MacOS
|
|
16
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Topic :: Office/Business
|
|
21
|
+
Classifier: Topic :: Text Processing :: Markup :: Markdown
|
|
22
|
+
Requires-Python: >=3.11
|
|
23
|
+
Requires-Dist: beautifulsoup4>=4.12
|
|
24
|
+
Requires-Dist: google-api-python-client>=2.100
|
|
25
|
+
Requires-Dist: google-auth-httplib2>=0.1
|
|
26
|
+
Requires-Dist: google-auth-oauthlib>=1.0
|
|
27
|
+
Requires-Dist: markdown-it-py>=3.0
|
|
28
|
+
Requires-Dist: markdownify>=0.11
|
|
29
|
+
Requires-Dist: requests>=2.31
|
|
30
|
+
Provides-Extra: dev
|
|
31
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
32
|
+
Requires-Dist: ruff>=0.4; extra == 'dev'
|
|
33
|
+
Provides-Extra: svg
|
|
34
|
+
Requires-Dist: cairosvg>=2.7; extra == 'svg'
|
|
35
|
+
Description-Content-Type: text/markdown
|
|
36
|
+
|
|
37
|
+
# skrepka 📎
|
|
38
|
+
|
|
39
|
+
ИИ-соавтор в Google Документах. Агент работает из вашего терминала прямо в документе: читает комментарии, отвечает на них и правит текст на месте.
|
|
40
|
+
|
|
41
|
+
[In English](https://github.com/slvfmts/skrepka/blob/main/README.en.md) · [Приватность](https://github.com/slvfmts/skrepka/blob/main/PRIVACY.md) · [Безопасность](https://github.com/slvfmts/skrepka/blob/main/SECURITY.md)
|
|
42
|
+
|
|
43
|
+
## Зачем
|
|
44
|
+
|
|
45
|
+
Работа над текстом с ИИ обычно идёт в двух окнах: документ и чат с агентом. Скопировать абзац в чат, вставить ответ обратно, руками починить оформление. Пока текст ходит туда-сюда, теряются правки и комментарии.
|
|
46
|
+
|
|
47
|
+
skrepka убирает это копирование. Вы оставляете по тексту обычные комментарии: про структуру, логику, формулировки. Потом зовёте агента в документ, он читает треды, отвечает и правит текст на месте. Заказчик приходит, комментирует там же, работа продолжается тем же способом. Комментарии при этом не рвутся: якоря остаются на месте, а закрывает треды только человек.
|
|
48
|
+
|
|
49
|
+
## Для кого
|
|
50
|
+
|
|
51
|
+
Редакторам, копирайтерам и контент-менеджерам, которые ведут и согласовывают тексты в Google Docs, а к работе подключают ИИ-агента: Claude Code, Codex или другого. Быть разработчиком не нужно, доступ к Google настраивает мастер `skrepka init`.
|
|
52
|
+
|
|
53
|
+
## Что умеет
|
|
54
|
+
|
|
55
|
+
Главный сценарий — разобрать комментарии. Вы говорите агенту «отработай комментарии», он читает треды, отвечает по делу и вносит правки в текст.
|
|
56
|
+
|
|
57
|
+
Кроме этого skrepka выгружает документ в markdown и заливает правки обратно, создаёт документы из markdown и разбирает предложенные правки. Полный список сценариев — в [docs/PLUGIN.md](https://github.com/slvfmts/skrepka/blob/main/docs/PLUGIN.md).
|
|
58
|
+
|
|
59
|
+
## Как начать
|
|
60
|
+
|
|
61
|
+
1. Поставьте skrepka: `pipx install skrepka`.
|
|
62
|
+
2. Настройте доступ к Google: `skrepka init`. Первая настройка занимает 15–30 минут, инструкция со снимками экрана — в [docs/QUICKSTART.md](https://github.com/slvfmts/skrepka/blob/main/docs/QUICKSTART.md).
|
|
63
|
+
3. Подключите навыки к агенту: [docs/PLUGIN.md](https://github.com/slvfmts/skrepka/blob/main/docs/PLUGIN.md).
|
|
64
|
+
|
|
65
|
+
Дальше попросите агента отработать комментарии в тестовом документе.
|
|
66
|
+
|
|
67
|
+
Вы заводите собственный проект Google Cloud и работаете от своего имени. У skrepka нет сервера и телеметрии: автор skrepka ваших документов и токенов не видит. Подробности в [PRIVACY.md](https://github.com/slvfmts/skrepka/blob/main/PRIVACY.md).
|
|
68
|
+
|
|
69
|
+
## Документация
|
|
70
|
+
|
|
71
|
+
| Файл | Что внутри |
|
|
72
|
+
|---|---|
|
|
73
|
+
| [docs/QUICKSTART.md](https://github.com/slvfmts/skrepka/blob/main/docs/QUICKSTART.md) | Настройка доступа к Google по шагам |
|
|
74
|
+
| [docs/PLUGIN.md](https://github.com/slvfmts/skrepka/blob/main/docs/PLUGIN.md) | Навыки для Claude Code и Codex |
|
|
75
|
+
| [docs/LIMITATIONS.md](https://github.com/slvfmts/skrepka/blob/main/docs/LIMITATIONS.md) | Что 0.9 не делает |
|
|
76
|
+
| [PRIVACY.md](https://github.com/slvfmts/skrepka/blob/main/PRIVACY.md) | Какие данные и куда идут |
|
|
77
|
+
| [SECURITY.md](https://github.com/slvfmts/skrepka/blob/main/SECURITY.md) | Модель угроз и как сообщить об уязвимости |
|
|
78
|
+
|
|
79
|
+
## Лицензия
|
|
80
|
+
|
|
81
|
+
MIT
|
skrepka-0.9.0/PRIVACY.md
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Приватность skrepka
|
|
2
|
+
|
|
3
|
+
skrepka — открытая утилита командной строки. Она даёт ИИ-агенту (Claude Code, OpenAI Codex и подобным) доступ к вашим Google Документам: читать, комментировать и править их.
|
|
4
|
+
|
|
5
|
+
## Кто видит ваши документы
|
|
6
|
+
|
|
7
|
+
У skrepka нет сервера и нет телеметрии, поэтому автор skrepka ваши данные не видит: документы, токены и текст к нему не попадают ни в каком виде.
|
|
8
|
+
|
|
9
|
+
Получателей ваших данных трое, и все трое — ваши. Google, где документы и так лежат: с ним skrepka общается от вашего имени. Ваш ИИ-провайдер, тот, на чьих серверах работает агент: Anthropic для Claude, OpenAI для Codex или другой, кого вы выбрали. И, на несколько секунд при вставке картинки, любой, кто знает прямую ссылку на неё в вашем Drive — об этом отдельно ниже.
|
|
10
|
+
|
|
11
|
+
Токен доступа к Google лежит у вас на диске.
|
|
12
|
+
|
|
13
|
+
## Кто есть кто
|
|
14
|
+
|
|
15
|
+
**Автор skrepka** поставляет вам код, и на этом всё. Сервера, телеметрии и доступа к вашим данным у него нет.
|
|
16
|
+
|
|
17
|
+
**Вы** создаёте собственный проект Google Cloud и собственный OAuth-клиент, то есть подключаетесь к Google от своего имени и своими ключами. Поэтому именно вы отвечаете за то, как используется этот доступ: за право работать с конкретным документом и за настройки приватности вашего ИИ-провайдера.
|
|
18
|
+
|
|
19
|
+
**ИИ-провайдера** выбираете вы. Агент работает на его серверах, и всё, что агент читает из ваших документов, отправляется этому провайдеру и обрабатывается по его условиям, а не по нашим.
|
|
20
|
+
|
|
21
|
+
## Какие данные и куда уходят
|
|
22
|
+
|
|
23
|
+
Поток данных двусторонний.
|
|
24
|
+
|
|
25
|
+
### Наружу, к агенту и его ИИ-провайдеру
|
|
26
|
+
|
|
27
|
+
Чтобы агент осмысленно работал с документом, ему уходит больше, чем просто текст: текст документа и комментариев, идентификаторы и ревизии, заголовки, структура, стили и ссылки, авторы и метаданные комментариев, предложенные правки (suggestions), изображения, а также выходные файлы, которые создаёт skrepka. Всё это попадает к вашему ИИ-провайдеру, потому что именно на его серверах живёт агент, который это читает.
|
|
28
|
+
|
|
29
|
+
### Обратно, изменения в ваших документах
|
|
30
|
+
|
|
31
|
+
По команде агента skrepka создаёт и изменяет документы, создаёт комментарии и ответы. Это реальные действия в вашем Google Drive, а не черновики; отменять их придётся вручную (частично помогает история версий Google Docs).
|
|
32
|
+
|
|
33
|
+
Удалять ваши документы skrepka не умеет: такой команды в ней нет, она удаляет только то, что создала сама (временные файлы картинок, тестовый документ в `init`). Но токен, который вы ей выдали, имеет полный доступ к Drive, поэтому граница здесь — не права, а набор команд.
|
|
34
|
+
|
|
35
|
+
### Изображения и временно публичный доступ
|
|
36
|
+
|
|
37
|
+
Когда skrepka вставляет изображение, Google Docs API требует, чтобы картинка была доступна по прямой ссылке. Поэтому во время вставки изображение становится временно публичным (`anyone:reader`), а затем публичный доступ снимается. Если процесс упадёт в неудачный момент, картинка может остаться публичной — тогда убрать её нужно вручную в вашем Google Drive.
|
|
38
|
+
|
|
39
|
+
Сама skrepka картинки со сторонних хостов не скачивает: при выгрузке документа она забирает только изображения с серверов Google, а внешние ссылки оставляет в `.md` как есть. Открывать их будет то, чем вы этот файл просматриваете, — не skrepka.
|
|
40
|
+
|
|
41
|
+
## Что происходит у ИИ-провайдера
|
|
42
|
+
|
|
43
|
+
Условия у каждого провайдера свои: сколько времени хранятся запросы, используются ли они для обучения моделей, могут ли их просматривать люди-ревьюеры, каких субподрядчиков он привлекает. skrepka на это не влияет и ничего за провайдера не гарантирует.
|
|
44
|
+
|
|
45
|
+
Проверьте сами, прежде чем дать агенту доступ к чувствительным документам:
|
|
46
|
+
|
|
47
|
+
- Claude / Anthropic. Проверьте настройки хранения и обучения в вашем тарифе; условия потребительских и корпоративных (API, Work, Enterprise) планов различаются. Выбирайте режим, где ваши данные не идут в обучение общей модели.
|
|
48
|
+
- Codex / OpenAI. Здесь так же: у API- и потребительских продуктов разные правила обучения и хранения.
|
|
49
|
+
- Любой другой провайдер. Найдите его условия хранения и обучения и убедитесь, что они вас устраивают. Если провайдер предлагает режим ручного просмотра (human review), считайте его отдельным риском для чувствительного контента.
|
|
50
|
+
|
|
51
|
+
## Где данные лежат на вашем компьютере
|
|
52
|
+
|
|
53
|
+
Ни одна из локальных копий не уходит автору skrepka.
|
|
54
|
+
|
|
55
|
+
**OAuth-токен доступа к Google** skrepka пишет с правами `0600` в конфигурационную директорию `~/.config/skrepka/`, которую создаёт с правами `0700`. Права `0600` мешают другим пользователям того же компьютера прочитать файл, но ничего не шифруют. Кто угодно с доступом к диску — украденный незашифрованный ноутбук, резервная копия, другой процесс под вашим же пользователем — сможет прочитать токен. По-настоящему данные «в покое» защищает только полнодисковое шифрование: FileVault на macOS, LUKS на Linux. Включите его, если работаете с чувствительными документами. Прозрачное шифрование самого токена (OS keyring / AEAD) в 0.9 не реализовано, появится в следующих версиях.
|
|
56
|
+
|
|
57
|
+
**Sidecar-файлы.** Когда вы скачиваете документ для локальной правки, рядом с вашим `.md` skrepka кладёт служебный sidecar с полным текстом документа — это база для слияния. Он лежит в вашей рабочей директории. Если это git-репозиторий, следите, чтобы полный текст не попал в коммит: sidecar-файлы стоит держать в `.gitignore`.
|
|
58
|
+
|
|
59
|
+
**Скачанные markdown и изображения** тоже лежат в вашей рабочей директории. Все файлы skrepka пишет с правами `0600`, директории с правами `0700`.
|
|
60
|
+
|
|
61
|
+
## Хранение и удаление данных
|
|
62
|
+
|
|
63
|
+
Локальными данными управляют три команды.
|
|
64
|
+
|
|
65
|
+
- `logout`. Убирает из локального хранилища токен доступа и все служебные (smoke/cleanup) токены, чтобы агент больше не мог обращаться к Google от вашего имени. OAuth-клиент (`credentials.json`) сохраняется, чтобы быстро подключиться заново. Доступ на стороне Google при этом не отзывается.
|
|
66
|
+
- `revoke`. Обращается к серверу Google и отзывает refresh-токен. Это сильнее `logout`. Предупреждение: отзыв может снять все разрешения для всего вашего OAuth-проекта и обесценить токены других клиентов этого же проекта. Если Google не подтвердил отзыв однозначно (таймаут, сетевая ошибка, неоднозначный ответ), skrepka оставит токен и сообщит, что результат неясен, вместо того чтобы делать вид, будто всё удалено.
|
|
67
|
+
- `forget`. Удаляет локальные артефакты: токен, `credentials.json`, служебные журналы и токены, файлы восстановления. Что удалить не удалось, команда перечислит отдельно. Файл блокировки (`.lock`) и сама директория остаются. По отдельному пути (`--sidecars PATH`) удаляет sidecar рядом с вашим документом, сам ваш `.md` не трогает. Есть предпросмотр: `--dry-run`.
|
|
68
|
+
|
|
69
|
+
**Чего локальное удаление не касается.** Оно стирает только локальные копии. За его пределами остаются копии, уже сохранённые у Google (документы, комментарии, история версий, оставшиеся публичными картинки), и копии у ИИ-провайдера — они хранятся по его политике. Так же за его пределами остаются данные в git-истории, резервных копиях и снапшотах.
|
|
70
|
+
|
|
71
|
+
## Про обучение моделей и данные Google
|
|
72
|
+
|
|
73
|
+
skrepka сама не собирает данные, не строит и не обучает никаких моделей и не передаёт данные автору (нет сервера, нет телеметрии). Данные Google уходят только тому ИИ-провайдеру, которого выбрали вы, и обрабатываются по его условиям. Поскольку вы работаете через собственный OAuth-проект, к нему применяется Google API Services User Data Policy. Режим без обучения на ваших данных выбираете у провайдера вы сами, skrepka этого не гарантирует.
|
|
74
|
+
|
|
75
|
+
## Ваша ответственность как владельца доступа
|
|
76
|
+
|
|
77
|
+
Доступ к Google идёт через ваш OAuth-проект и ваши ключи, поэтому:
|
|
78
|
+
|
|
79
|
+
- у вас должны быть полномочия работать с документом. Если вы правите или комментируете чужой документ (заказчика, Shared Drive), убедитесь, что владелец дал вам на это право. skrepka ваши полномочия технически не проверяет, она действует от вашего имени;
|
|
80
|
+
- если вы публикуете свой OAuth-клиент как публичное приложение, на вас ложатся требования Google: политика приватности, возможная верификация и аудит CASA. Для персонального использования это обычно не требуется.
|
|
81
|
+
|
|
82
|
+
## Статус 0.9
|
|
83
|
+
|
|
84
|
+
Вы работаете через собственный Google-проект и от своего имени; это не приложение, в которое входят под общей учётной записью. Верификацию Google, если она вообще нужна, проходит ваш проект, а не автор skrepka. Технические детали защит на уровне CLI (гейты на резолв комментариев и на деструктивную перезапись, безопасный ввод-вывод) описаны в [SECURITY.md](SECURITY.md). На этом этапе skrepka показывает, какие данные куда идут, и даёт ими управлять, но не гарантирует соответствие требованиям Google.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# skrepka 📎
|
|
2
|
+
|
|
3
|
+
An AI co-author in Google Docs. The agent works from your terminal inside the document itself: it reads the comments, replies to them, and edits the text in place.
|
|
4
|
+
|
|
5
|
+
*In Russian: [README.md](README.md).*
|
|
6
|
+
|
|
7
|
+
## Why
|
|
8
|
+
|
|
9
|
+
Working on text with an AI usually means two windows: the document and a chat with the agent. Copy a paragraph into the chat, paste the answer back, fix the formatting by hand. While the text travels back and forth, edits and comments get lost.
|
|
10
|
+
|
|
11
|
+
skrepka removes the copying. You leave ordinary comments in the text about structure, logic, and wording. Then you point the agent at the document; it reads the threads, replies, and edits the text in place. Your client shows up, comments in the same document, and the work continues the same way. The comments survive: anchors stay put, and only a human closes a thread.
|
|
12
|
+
|
|
13
|
+
## Who it is for
|
|
14
|
+
|
|
15
|
+
Editors, copywriters, and content managers who run and sign off documents in Google Docs and bring an AI agent into the work: Claude Code, Codex, or another one. You do not need to be a developer; the `skrepka init` wizard sets up Google access for you.
|
|
16
|
+
|
|
17
|
+
## What it does
|
|
18
|
+
|
|
19
|
+
The main scenario is working through comments. You tell the agent to handle the comments; it reads the threads, replies to the point, and edits the text.
|
|
20
|
+
|
|
21
|
+
skrepka also exports a document to markdown and pushes edits back, creates documents from markdown, and reviews suggested changes. Full list of scenarios in [docs/PLUGIN.md](docs/PLUGIN.md).
|
|
22
|
+
|
|
23
|
+
## Getting started
|
|
24
|
+
|
|
25
|
+
1. Install skrepka: `pipx install skrepka`.
|
|
26
|
+
2. Set up Google access: `skrepka init`. First-time setup takes 15 to 30 minutes; the walkthrough with screenshots is in [docs/QUICKSTART.md](docs/QUICKSTART.md).
|
|
27
|
+
3. Connect the skills to your agent: [docs/PLUGIN.md](docs/PLUGIN.md).
|
|
28
|
+
|
|
29
|
+
Then ask the agent to work through the comments in a test document.
|
|
30
|
+
|
|
31
|
+
You create your own Google Cloud project and act under your own account. skrepka has no server and no telemetry: its author never sees your documents or your tokens. Details in [PRIVACY.md](PRIVACY.md).
|
|
32
|
+
|
|
33
|
+
## Docs
|
|
34
|
+
|
|
35
|
+
| File | What's inside |
|
|
36
|
+
|---|---|
|
|
37
|
+
| [docs/QUICKSTART.md](docs/QUICKSTART.md) | Step-by-step Google authorization |
|
|
38
|
+
| [docs/PLUGIN.md](docs/PLUGIN.md) | Connecting the skills to your agent |
|
|
39
|
+
| [docs/LIMITATIONS.md](docs/LIMITATIONS.md) | What 0.9 deliberately does not do |
|
|
40
|
+
| [PRIVACY.md](PRIVACY.md) | What data goes where |
|
|
41
|
+
| [SECURITY.md](SECURITY.md) | Threat model and how to report a vulnerability |
|
|
42
|
+
|
|
43
|
+
## License
|
|
44
|
+
|
|
45
|
+
MIT
|
skrepka-0.9.0/README.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# skrepka 📎
|
|
2
|
+
|
|
3
|
+
ИИ-соавтор в Google Документах. Агент работает из вашего терминала прямо в документе: читает комментарии, отвечает на них и правит текст на месте.
|
|
4
|
+
|
|
5
|
+
[In English](https://github.com/slvfmts/skrepka/blob/main/README.en.md) · [Приватность](https://github.com/slvfmts/skrepka/blob/main/PRIVACY.md) · [Безопасность](https://github.com/slvfmts/skrepka/blob/main/SECURITY.md)
|
|
6
|
+
|
|
7
|
+
## Зачем
|
|
8
|
+
|
|
9
|
+
Работа над текстом с ИИ обычно идёт в двух окнах: документ и чат с агентом. Скопировать абзац в чат, вставить ответ обратно, руками починить оформление. Пока текст ходит туда-сюда, теряются правки и комментарии.
|
|
10
|
+
|
|
11
|
+
skrepka убирает это копирование. Вы оставляете по тексту обычные комментарии: про структуру, логику, формулировки. Потом зовёте агента в документ, он читает треды, отвечает и правит текст на месте. Заказчик приходит, комментирует там же, работа продолжается тем же способом. Комментарии при этом не рвутся: якоря остаются на месте, а закрывает треды только человек.
|
|
12
|
+
|
|
13
|
+
## Для кого
|
|
14
|
+
|
|
15
|
+
Редакторам, копирайтерам и контент-менеджерам, которые ведут и согласовывают тексты в Google Docs, а к работе подключают ИИ-агента: Claude Code, Codex или другого. Быть разработчиком не нужно, доступ к Google настраивает мастер `skrepka init`.
|
|
16
|
+
|
|
17
|
+
## Что умеет
|
|
18
|
+
|
|
19
|
+
Главный сценарий — разобрать комментарии. Вы говорите агенту «отработай комментарии», он читает треды, отвечает по делу и вносит правки в текст.
|
|
20
|
+
|
|
21
|
+
Кроме этого skrepka выгружает документ в markdown и заливает правки обратно, создаёт документы из markdown и разбирает предложенные правки. Полный список сценариев — в [docs/PLUGIN.md](https://github.com/slvfmts/skrepka/blob/main/docs/PLUGIN.md).
|
|
22
|
+
|
|
23
|
+
## Как начать
|
|
24
|
+
|
|
25
|
+
1. Поставьте skrepka: `pipx install skrepka`.
|
|
26
|
+
2. Настройте доступ к Google: `skrepka init`. Первая настройка занимает 15–30 минут, инструкция со снимками экрана — в [docs/QUICKSTART.md](https://github.com/slvfmts/skrepka/blob/main/docs/QUICKSTART.md).
|
|
27
|
+
3. Подключите навыки к агенту: [docs/PLUGIN.md](https://github.com/slvfmts/skrepka/blob/main/docs/PLUGIN.md).
|
|
28
|
+
|
|
29
|
+
Дальше попросите агента отработать комментарии в тестовом документе.
|
|
30
|
+
|
|
31
|
+
Вы заводите собственный проект Google Cloud и работаете от своего имени. У skrepka нет сервера и телеметрии: автор skrepka ваших документов и токенов не видит. Подробности в [PRIVACY.md](https://github.com/slvfmts/skrepka/blob/main/PRIVACY.md).
|
|
32
|
+
|
|
33
|
+
## Документация
|
|
34
|
+
|
|
35
|
+
| Файл | Что внутри |
|
|
36
|
+
|---|---|
|
|
37
|
+
| [docs/QUICKSTART.md](https://github.com/slvfmts/skrepka/blob/main/docs/QUICKSTART.md) | Настройка доступа к Google по шагам |
|
|
38
|
+
| [docs/PLUGIN.md](https://github.com/slvfmts/skrepka/blob/main/docs/PLUGIN.md) | Навыки для Claude Code и Codex |
|
|
39
|
+
| [docs/LIMITATIONS.md](https://github.com/slvfmts/skrepka/blob/main/docs/LIMITATIONS.md) | Что 0.9 не делает |
|
|
40
|
+
| [PRIVACY.md](https://github.com/slvfmts/skrepka/blob/main/PRIVACY.md) | Какие данные и куда идут |
|
|
41
|
+
| [SECURITY.md](https://github.com/slvfmts/skrepka/blob/main/SECURITY.md) | Модель угроз и как сообщить об уязвимости |
|
|
42
|
+
|
|
43
|
+
## Лицензия
|
|
44
|
+
|
|
45
|
+
MIT
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Безопасность skrepka
|
|
2
|
+
|
|
3
|
+
Здесь модель угроз, встроенные защиты и порядок сообщения об уязвимости. Про то, какие данные и куда уходят, есть отдельный документ [PRIVACY.md](PRIVACY.md).
|
|
4
|
+
|
|
5
|
+
skrepka 0.9 — предрелиз. Защиты, описанные ниже, покрыты тестами, но это ещё не проверенное Google приложение.
|
|
6
|
+
|
|
7
|
+
## Как сообщить об уязвимости
|
|
8
|
+
|
|
9
|
+
Публичный issue для уязвимости не открывайте. Есть два приватных канала:
|
|
10
|
+
|
|
11
|
+
- GitHub: вкладка Security → Report a vulnerability (private vulnerability reporting) в репозитории `slvfmts/skrepka`;
|
|
12
|
+
- письмо на hello@editors.one с темой, начинающейся на `[skrepka security]`.
|
|
13
|
+
|
|
14
|
+
Что приложить: версию skrepka, ОС и версию Python, шаги воспроизведения. Для проблем с файловым вводом-выводом — точную раскладку путей и прав.
|
|
15
|
+
|
|
16
|
+
Проект некоммерческий, гарантированных сроков ответа нет. Исправление выходит в ближайшем патч-релизе, кредит в релизных заметках указываем по вашему желанию.
|
|
17
|
+
|
|
18
|
+
## Поддерживаемые версии
|
|
19
|
+
|
|
20
|
+
skrepka в стадии 0.9 (предрелиз). Исправления безопасности выходят только для последнего релиза линии 0.9.x. Более ранних поддерживаемых веток нет.
|
|
21
|
+
|
|
22
|
+
## Модель угроз
|
|
23
|
+
|
|
24
|
+
**От чего защищаем.** skrepka пишет артефакты — скачанный документ, изображения, sidecar, файл `--output` — в ту рабочую директорию, где вы запускаете команду. Цепочку владельцев этой директории skrepka не контролирует. Главная угроза: симлинк или хардлинк, подложенный по предсказуемому пути. Наивный `open(path, "w")` пошёл бы по такой ссылке и переписал содержимым документа произвольный файл, доступный вам на запись, например `~/.ssh/authorized_keys`. Сценарий реален в общих и world-writable каталогах: `/tmp`, расшаренные рабочие директории.
|
|
25
|
+
|
|
26
|
+
**Где проведена граница.** Защита покрывает имя целевого файла и его непосредственную родительскую директорию, то есть предсказуемые, угадываемые имена. Здесь skrepka работает через `O_NOFOLLOW` и эксклюзивное создание: симлинк на этой позиции приводит к отказу (fail closed).
|
|
27
|
+
|
|
28
|
+
Директории выше непосредственного родителя относятся к вашей существующей среде, и симлинки в них разыменовываются намеренно. Так работает файловая система, и на macOS иначе нельзя: `/var`, `/tmp`, `/etc` сами ведут в `/private` через симлинки. К тому же тот, кто может подложить симлинк в дальний предок, уже имеет доступ на запись в ваше дерево.
|
|
29
|
+
|
|
30
|
+
**Что вне модели угроз.**
|
|
31
|
+
|
|
32
|
+
- Атакующий под вашим же пользователем (тот же UID). Он и так может прочитать токен и ваши файлы. Права `0600`/`0700` закрывают файлы от других пользователей машины, но не шифруют их; подробнее в [PRIVACY.md](PRIVACY.md).
|
|
33
|
+
- Windows. В 0.9 не поддержан; защиты файлового I/O работают только на Unix (`openat`, `O_NOFOLLOW`, dir-fd).
|
|
34
|
+
- Гранулярный контроль каждого действия агента. Вне скоупа 0.9, см. ниже про человеческий гейт и prompt-injection.
|
|
35
|
+
|
|
36
|
+
## Встроенные защиты
|
|
37
|
+
|
|
38
|
+
### Аутентификация и доступ
|
|
39
|
+
|
|
40
|
+
skrepka запрашивает единственный OAuth-scope: `https://www.googleapis.com/auth/drive`. Более узкий `drive.file` неприменим: он ломает ключевой сценарий с чужим документом, к которому обращаются по его ID или через Shared Drive. Дополнительные scope, включая `documents`, не запрашиваются — `drive` уже покрывает нужные вызовы Docs API.
|
|
41
|
+
|
|
42
|
+
Токен хранится с правами `0600` в конфиг-директории `~/.config/skrepka/` (`0700`). Рефреш с сокращённым набором scope на диск не сохраняется, иначе урезанный грант молча стал бы рабочим при следующем запуске.
|
|
43
|
+
|
|
44
|
+
### Файловый I/O
|
|
45
|
+
|
|
46
|
+
Все артефакты пишутся через модуль `safeio`. Непосредственный родитель открывается `O_NOFOLLOW` и создаётся эксклюзивным `mkdir` с правами `0700`. Запись идёт в непредсказуемый временный файл (`O_EXCL|O_NOFOLLOW`), затем атомарный `rename` поверх цели. `rename` заменяет имя: он не пишет сквозь симлинк и не усекает хардлинкнутый inode. Существующая нерегулярная цель отвергается явно.
|
|
47
|
+
|
|
48
|
+
### Человеческий гейт
|
|
49
|
+
|
|
50
|
+
У гейта два уровня, и гарантии у них разные.
|
|
51
|
+
|
|
52
|
+
**Механический барьер, вшитый в код.** Резолв комментария (`resolve`, `reply --resolve`) и деструктивное полное обновление документа (`update --acknowledge-loss`) требуют подтверждения: интерактивный запрос в TTY, по умолчанию «нет». Единственный неинтерактивный обход — переменная окружения `SKREPKA_ASSUME_HUMAN=1`, которую выставляет сам человек. Гейт на `update` срабатывает, когда в документе есть комментарии или именованные диапазоны; документ без тех и других перезаписывается без вопроса.
|
|
53
|
+
|
|
54
|
+
Гарантии «ответил именно человек» механический барьер не даёт: агент, выделивший псевдотерминал, технически способен ответить на запрос сам. Идентичность человека держится на договорённости ([`agents/CONTRACT.md`](agents/CONTRACT.md)), а не на криптографии. По контракту агент комментарии не резолвит.
|
|
55
|
+
|
|
56
|
+
**Уровень договорённости, без машинного барьера.** `revoke` и `forget` в неинтерактивном запуске без `--yes` отказывают, но сам флаг `--yes` агент технически может передать. `logout` подтверждения не спрашивает вовсе, он лишь убирает локальный токен. Запрет запускать эти команды за человека записан в правилах для агента ([`agents/CONTRACT.md`](agents/CONTRACT.md)). Это команды для человека.
|
|
57
|
+
|
|
58
|
+
### Изображения
|
|
59
|
+
|
|
60
|
+
Вставка картинки требует временно публичной прямой ссылки: на время вставки файл становится `anyone:reader`, затем доступ снимается. Детали, риск при неудачном падении и рекомендации описаны в [PRIVACY.md](PRIVACY.md).
|
|
61
|
+
|
|
62
|
+
### Prompt-injection
|
|
63
|
+
|
|
64
|
+
skrepka считает текст документов и комментариев данными, а не инструкциями. Навыки для агента (см. [`agents/CONTRACT.md`](agents/CONTRACT.md)) обязаны не выполнять просьбы, встреченные внутри комментариев или текста, без подтверждения человека.
|
|
65
|
+
|
|
66
|
+
### Без телеметрии
|
|
67
|
+
|
|
68
|
+
У skrepka нет сервера, нет сбора данных и нет исходящих соединений, кроме API самого Google. Картинки она забирает только с Google-хостов, сторонние URL из документа не запрашивает вовсе — это заодно закрывает SSRF. Автор skrepka ваших данных не получает.
|
|
69
|
+
|
|
70
|
+
## Гигиена репозитория
|
|
71
|
+
|
|
72
|
+
Секреты (`credentials.json`, `client_secret_*.json`, `token.json`, `*.token.json`, `.env`) перечислены в `.gitignore` и не должны попадать в коммиты. gitleaks прогоняется по всей истории в CI на каждый push и в release-workflow перед публикацией. Артефакты рантайма (`*.gdocs-base.json`, журналы синка) тоже в `.gitignore`: sidecar содержит полный текст документа.
|