Files
AX-Copilot-Codex/src/AxCopilot/Handlers/JournalHandler.cs

133 lines
4.8 KiB
C#

using System.IO;
using System.Text;
using System.Windows;
using AxCopilot.SDK;
using AxCopilot.Services;
using AxCopilot.Themes;
namespace AxCopilot.Handlers;
/// <summary>
/// 업무 일지 자동 생성 핸들러. "journal" 프리픽스로 사용합니다.
/// UsageStatisticsService 데이터를 기반으로 오늘/지정일의 업무 요약을 자동 생성합니다.
/// 예: journal → 오늘의 업무 일지 생성
/// journal 2026-03-25 → 해당 날짜 일지
/// Enter → 마크다운 형식으로 클립보드에 복사.
/// </summary>
public class JournalHandler : IActionHandler
{
public string? Prefix => "journal";
public PluginMetadata Metadata => new(
"Journal",
"업무 일지 자동 생성 — journal",
"1.0",
"AX");
public Task<IEnumerable<LauncherItem>> GetItemsAsync(string query, CancellationToken ct)
{
var q = query.Trim();
DateTime targetDate;
if (string.IsNullOrWhiteSpace(q))
targetDate = DateTime.Today;
else if (DateTime.TryParse(q, out var parsed))
targetDate = parsed.Date;
else
{
return Task.FromResult<IEnumerable<LauncherItem>>(
[
new LauncherItem("날짜 형식 오류", "예: journal 2026-03-25 또는 journal (오늘)",
null, null, Symbol: Symbols.Warning)
]);
}
// 날짜 범위 계산 (오늘~targetDate 간 차이)
var daysAgo = (DateTime.Today - targetDate).Days;
var allStats = UsageStatisticsService.GetStats(Math.Max(daysAgo + 1, 1));
var stats = allStats.FirstOrDefault(s => s.Date == targetDate.ToString("yyyy-MM-dd"));
var items = new List<LauncherItem>();
if (stats == null)
{
items.Add(new LauncherItem(
$"{targetDate:yyyy-MM-dd} — 기록 없음",
"해당 날짜의 사용 기록이 없습니다",
null, null, Symbol: Symbols.Info));
return Task.FromResult<IEnumerable<LauncherItem>>(items);
}
// 요약 생성
var activeHours = stats.ActiveSeconds / 3600.0;
var sb = new StringBuilder();
sb.AppendLine($"## 업무 일지 — {targetDate:yyyy-MM-dd} ({targetDate:dddd})");
sb.AppendLine();
sb.AppendLine($"- **PC 활성 시간**: {activeHours:F1}시간");
sb.AppendLine($"- **런처 호출**: {stats.LauncherOpens}회");
if (stats.CommandUsage.Count > 0)
{
sb.AppendLine();
sb.AppendLine("### 사용한 명령어");
foreach (var kv in stats.CommandUsage.OrderByDescending(x => x.Value).Take(10))
sb.AppendLine($"- `{kv.Key}` — {kv.Value}회");
}
sb.AppendLine();
sb.AppendLine("---");
sb.AppendLine($"*AX Copilot 자동 생성 · {DateTime.Now:HH:mm}*");
var journal = sb.ToString();
// 요약 카드
var topCmds = stats.CommandUsage.OrderByDescending(x => x.Value).Take(3)
.Select(x => x.Key);
var cmdPreview = stats.CommandUsage.Count > 0
? $"주요 명령: {string.Join(", ", topCmds)}"
: "명령어 사용 기록 없음";
items.Add(new LauncherItem(
$"{targetDate:yyyy-MM-dd} 업무 일지 — 클립보드로 복사",
$"활성 {activeHours:F1}h · 런처 {stats.LauncherOpens}회 · {cmdPreview}",
null, journal,
Symbol: Symbols.Note));
items.Add(new LauncherItem(
$"PC 활성 시간: {activeHours:F1}시간",
"잠금 해제 시간 기준 누적",
null, $"PC 활성 시간: {activeHours:F1}시간",
Symbol: Symbols.Clock));
items.Add(new LauncherItem(
$"런처 호출: {stats.LauncherOpens}회",
"Alt+Space 또는 트레이 클릭",
null, $"런처 호출: {stats.LauncherOpens}회",
Symbol: Symbols.Search));
if (stats.CommandUsage.Count > 0)
{
foreach (var kv in stats.CommandUsage.OrderByDescending(x => x.Value).Take(5))
{
items.Add(new LauncherItem(
$"{kv.Key} — {kv.Value}회",
"Enter로 복사",
null, $"{kv.Key}: {kv.Value}회",
Symbol: Symbols.Terminal));
}
}
return Task.FromResult<IEnumerable<LauncherItem>>(items);
}
public Task ExecuteAsync(LauncherItem item, CancellationToken ct)
{
if (item.Data is string text && !string.IsNullOrWhiteSpace(text))
{
try { Application.Current?.Dispatcher.Invoke(() => Clipboard.SetText(text)); }
catch { }
NotificationService.Notify("업무 일지", "클립보드에 복사되었습니다");
}
return Task.CompletedTask;
}
}