trackit_history
Lightweight modular logger for Dart and Flutter
Install / Use
npx skills add unger1984/trackitInstalls into whichever agent you are using.
Cursor Rules
Cursor IDE rules (v2)
Quality Score
Category
Development & EngineeringSupported Platforms
Tags
Our assessment of trackit_history
trackit_history scores 64/100 on our quality scale, 3960th of 4,614 Development & Engineering skills we index.
Its Cursor Rules is 16 KB long, well organised into 51 sections with 41 code examples: a thorough specification that gives an agent plenty to work with.
It has no GitHub stars yet, so there is no community track record; judge it on its content.
Maintenance, license and trust
- We could not determine when the repository was last updated.
- Our last check on 2026-10-20 found the source still online.
- No license is declared. By default that means all rights are reserved: you can read it, but reusing or redistributing it is not clearly permitted. Ask the author before building on it commercially.
- Its trust signals score 68/100, with 3 cautions from licensing, adoption, age or documentation. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.
Safety scan
No issues foundOur scan of the whole file found no instruction hijacking, hidden characters, credential access, data exfiltration or destructive commands. An AI review of the same text found nothing harmful.
AI review by kimi-k2.7-code on 2026-09-25. Automated pattern scan on 2026-09-24. It catches known dangerous patterns, not every risk — read a skill before letting an agent act on it.
trackit_history compared with similar skills
All 4 of these similar skills score higher than trackit_history; compare them before choosing.
| Skill | Score | Stars | Updated | Format |
|---|---|---|---|---|
| trackit_history (this skill)by unger1984 | 64 | 0 | — | Cursor Rules |
| taste-skillby Leonxlnx | 100 | 111.0k | 1d ago | CLAUDE.md |
| ai-job-searchby ai-job-search-dev | 100 | 70.0k | today | CLAUDE.md |
| claude-howtoby luongnv89 | 100 | 46.6k | 3d ago | CLAUDE.md |
| lobehubby lobehub | 100 | 84.2k | today | MCP Server |
Frequently asked questions
- How do I install trackit_history?
- Run
npx skills add unger1984/trackit. The install tabs above show the steps for each supported agent. - Which AI agents does trackit_history work with?
- It is written for Cursor, as a Cursor Rules file. Other agents that read the same format can often use it too.
- Is trackit_history safe to use?
- Our scan of the whole file found no instruction hijacking, hidden characters, credential access, data exfiltration or destructive commands. An AI review of the same text found nothing harmful. It declares no license and scores 68/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
- Is trackit_history still maintained?
- We could not determine when the repository was last updated.
Skill content
View source on GitHubTrackIt History Package — Правила разработки
О пакете
trackit_history — модуль-расширение для хранения логов в памяти. Подписывается на поток событий из базового trackit и сохраняет их в FIFO очереди с ограничением по размеру.
Архитектурные паттерны
Singleton Pattern
Глобальное хранилище истории как singleton:
class TrackitHistory {
factory TrackitHistory() => _instance;
TrackitHistory._internal();
static final TrackitHistory _instance = TrackitHistory._internal();
final TrackitHistoryList _history = [];
int _maxSize = 1000;
}
Правила:
- Factory конструктор для доступа к единственному экземпляру
- Приватный конструктор
_internal() - Статическое поле
_instanceс eager initialization - Приватные поля для хранения состояния
FIFO Queue Pattern
Очередь с автоматическим удалением старых элементов:
void add(LogEvent event) {
_history.add(event);
while (_history.length > _maxSize) {
_history.removeAt(0); // Удаление самого старого
}
}
Правила:
- Добавление в конец списка (
add) - Удаление из начала списка (
removeAt(0)) - Проверка размера после каждого добавления
- Использовать
while, неifдля корректной обработки измененияmaxSize
Immutable Access Pattern
Защита от внешних изменений:
TrackitHistoryList get history => List.unmodifiable(_history);
Правила:
- Возвращать
List.unmodifiable()для предотвращения изменений - Внутреннее хранилище остается приватным
- Все изменения только через публичные методы класса
Структура класса
TrackitHistory (Singleton)
class TrackitHistory {
factory TrackitHistory() => _instance;
TrackitHistory._internal();
static final TrackitHistory _instance = TrackitHistory._internal();
final TrackitHistoryList _history = [];
int _maxSize = 1000;
/// Добавляет событие в историю
void add(LogEvent event) {
_history.add(event);
while (_history.length > _maxSize) {
_history.removeAt(0);
}
}
/// Возвращает неизменяемую копию истории
TrackitHistoryList get history => List.unmodifiable(_history);
/// Устанавливает максимальный размер истории
void setMaxSize(int size) {
_maxSize = size;
while (_history.length > _maxSize) {
_history.removeAt(0);
}
}
/// Очищает всю историю
void clear() {
_history.clear();
}
}
Ответственность:
- Хранение событий в памяти
- Управление размером истории
- Предоставление доступа к истории
TrackitHistoryList (Type Alias)
typedef TrackitHistoryList = List<LogEvent>;
Правила:
- Простой type alias для ясности API
- Используется для возвращаемых значений
- Подчеркивает назначение списка
API дизайн
Добавление событий
void add(LogEvent event)
Правила:
- Единственный параметр —
LogEvent - Void return type (side effect)
- Автоматически управляет размером
- Синхронный метод
Доступ к истории
TrackitHistoryList get history
Правила:
- Геттер, не метод
- Возвращает неизменяемый список
- O(n) операция (создается новый список)
- Не кешировать результат на стороне клиента
Установка максимального размера
void setMaxSize(int size)
Правила:
- Положительное целое число
- Применяется немедленно (удаляет лишние элементы)
- Может уменьшить текущую историю
- Default значение: 1000
Очистка истории
void clear()
Правила:
- Удаляет все события
- Не изменяет
maxSize - Используется для reset состояния
- Полезно для тестов и hot reload
Управление памятью
Ограничение размера
Default значение:
int _maxSize = 1000;
Правила:
- По умолчанию 1000 событий
- Можно изменить через
setMaxSize() - Рассчитывать потребление памяти: ~1000 событий ≈ 100-500 KB
- Для long-running приложений рекомендуется ограничивать размер
Автоматическая очистка
while (_history.length > _maxSize) {
_history.removeAt(0);
}
Правила:
- Очистка происходит при добавлении нового события
- Удаляются самые старые события (FIFO)
- Использовать
while, неif(корректно обрабатывает уменьшение maxSize) - O(n) сложность при удалении (допустимо для небольших n)
Оптимизация производительности
Для больших историй:
// Рассмотреть использование Queue вместо List
import 'dart:collection';
final Queue<LogEvent> _history = Queue();
void add(LogEvent event) {
_history.add(event);
while (_history.length > _maxSize) {
_history.removeFirst(); // O(1) вместо O(n)
}
}
Правила:
- Для
maxSize > 10000рассмотретьQueue removeFirst()в Queue — O(1) vsremoveAt(0)в List — O(n)- Компромисс: Queue требует больше памяти
Использование
Базовое использование
import 'package:trackit/trackit.dart';
import 'package:trackit_history/trackit_history.dart';
void main() {
// Подключение хранилища истории
Trackit().listen((event) {
TrackitHistory().add(event);
});
// Создание логгера
final log = Trackit.create('MyApp');
// Логирование
log.info('Event 1');
log.info('Event 2');
// Доступ к истории
final history = TrackitHistory().history;
print('Total events: ${history.length}');
}
Упрощенная подписка
// Короткая форма
Trackit().listen(TrackitHistory().add);
С ограничением размера
void main() {
// Установка максимального размера
TrackitHistory().setMaxSize(500);
// Подключение
Trackit().listen(TrackitHistory().add);
}
Фильтрация событий
// Сохранять только ошибки
Trackit().listen((event) {
if (event.level is LogLevelError || event.level is LogLevelFatal) {
TrackitHistory().add(event);
}
});
Периодическая очистка
// Очищать историю каждый час
Timer.periodic(Duration(hours: 1), (_) {
TrackitHistory().clear();
});
Доступ к истории
Получение всех событий
final allEvents = TrackitHistory().history;
Фильтрация по уровню
final errors = TrackitHistory()
.history
.where((e) => e.level is LogLevelError)
.toList();
Фильтрация по времени
final lastHour = DateTime.now().subtract(Duration(hours: 1));
final recentEvents = TrackitHistory()
.history
.where((e) => e.time != null && e.time!.isAfter(lastHour))
.toList();
Фильтрация по title
final serviceEvents = TrackitHistory()
.history
.where((e) => e.title == 'MyService')
.toList();
Сортировка
// По времени (по возрастанию)
final sorted = TrackitHistory()
.history
.sorted((a, b) => a.compareTo(b));
// По времени (по убыванию)
final reversed = TrackitHistory()
.history
.sorted((a, b) => b.compareTo(a));
Последние N событий
final last10 = TrackitHistory()
.history
.reversed
.take(10)
.toList();
Интеграция с UI
Flutter: Отображение истории логов
class LogHistoryScreen extends StatelessWidget {
const LogHistoryScreen({super.key});
@override
Widget build(BuildContext context) {
final history = TrackitHistory().history.reversed.toList();
return ListView.builder(
itemCount: history.length,
itemBuilder: (context, index) {
final event = history[index];
return ListTile(
leading: Icon(_getIconForLevel(event.level)),
title: Text(event.message),
subtitle: Text('${event.title} • ${event.time}'),
);
},
);
}
}
Реактивное обновление
class LogHistoryProvider extends ChangeNotifier {
List<LogEvent> get history => TrackitHistory().history;
void _updateHistory(LogEvent event) {
TrackitHistory().add(event);
notifyListeners();
}
void init() {
Trackit().listen(_updateHistory);
}
}
Stream для UI
// Создать Stream для реактивного UI
Stream<TrackitHistoryList> get historyStream async* {
await for (final _ in Trackit()) {
yield TrackitHistory().history;
}
}
Экспорт истории
В JSON
String exportToJson() {
final history = TrackitHistory().history;
final json = history.map((event) => {
'level': event.level.toString(),
'title': event.title,
'message': event.message,
'time': event.time?.toIso8601String(),
'exception': event.exception?.toString(),
'stackTrace': event.stackTrace?.toString(),
}).toList();
return jsonEncode(json);
}
В текстовый файл
Future<void> exportToFile(String path) async {
final history = TrackitHistory().history;
final buffer = StringBuffer();
for (final event in history) {
buffer.writeln('[${event.level}] ${event.time} - ${event.title}');
buffer.writeln(' ${event.message}');
if (event.exception != null) {
buffer.writeln(' Exception: ${event.exception}');
}
buffer.writeln();
}
final file = File(path);
await file.writeAsString(buffer.toString());
}
Зависимости
dependencies:
trackit: ^0.1.0 # Базовый пакет
meta: ^1.15.0
dev_dependencies:
lints: ^5.0.0
test: ^1.25.8
Правила:
- Зависимость от базового
trackit - Никаких других runtime зависимостей
- Чистый Dart код без platform-specific логики
Тестирование
Что тестировать
- Добавление событий в историю
- Ограничение по размеру (FIFO)
- Изменение maxSize с удалением лишних элементов
- Очистка истории
- Неизменяемость возвращаемого списка
- Singleton поведение
Пример теста
import 'package:test/test.dart';
import 'package:trackit/trackit.dart';
import 'package:trackit_history/trackit_history.dart';
void main() {
setUp(() {
TrackitHistory().clear();
});
group('TrackitHistory', () {
test('should add events to history', () {
final event = LogEvent(
level: const LogLevel.info(),
title: 'Test',
message: 'Test message',
);
TrackitHistory().add(event);
expect(TrackitHistory().history.length, equals(1));
expect(TrackitHistory().history.first, equals(event));
});
test('should limit history size', () {
TrackitHistory().setMaxSize(3);
for (var i = 0; i < 5; i++) {
TrackitHistory().add(LogEvent(
level: const LogLevel.info(),
title: 'Test',
message: 'Message $i',
));
}
expect(TrackitHistory().history.length, equals(3));
expect(TrackitHistory().history.last.message, equals('Message 4'));
expect(TrackitHistory().history.first.message, equals('Message 2'));
});
test('should clear history', () {
TrackitHistory().add(LogEvent(
level: const LogLevel.info(),
title: 'Test',
message: 'Test',
));
expect(TrackitHistory().history.length, equals(1));
TrackitHistory().clear();
expect(TrackitHistory().history.length, equals(0));
});
test('should return unmodifiable list', () {
final history = TrackitHistory().history;
expect(
() => history.add(LogEvent(
level: const LogLevel.info(),
title: 'Test',
message: 'Test',
)),
throwsUnsupportedError,
);
});
test('should be singleton', () {
final instance1 = TrackitHistory();
final instance2 = TrackitHistory();
expect(identical(instance1, instance2), isTrue);
});
});
}
Best Practices
- Установить разумный maxSize: Для production рекомендуется 500-2000 событий в зависимости от частоты логирования
- Фильтровать перед добавлением: Для экономии памяти фильтровать события по уровню или источнику
- Периодическая очистка: Для long-running приложений настроить автоматическую очистку
- Не злоупотреблять доступом: Геттер
historyсоздает новый список — кешировать результат если нужно - Использовать для отладки: В production отключать или ограничивать размер для экономии памяти
Антипаттерны
❌ **Хранение
Truncated for display — read the full file on GitHub.
Related Skills
taste-skill
111.0kAgent skills that give coding agents taste: art direction, reference images and a browser check instead of generic AI pages
ai-job-search
70.0kThe job search that runs on your machine. AI job application framework built on Claude Code: evaluate postings, tailor CVs, write cover letters, prep interviews. Fork it and own it.
claude-howto
46.6kA visual, example-driven guide to Claude Code — from basic concepts to advanced agents, with copy-paste templates that bring immediate value.
lobehub
84.2k🤯 LobeHub - Super-Agents on Your Team. Add super-agents to the chats your team already uses.They take on work by themselves and get better every week.
Trust signals
From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.
