# AX Commander

Windows 전용 시맨틱 런처 & 워크스페이스 매니저

> Alfred (macOS)에서 영감을 받아 Windows 환경에 최적화된 키보드 중심 생산성 도구입니다.

---

## 주요 기능 (프리픽스 치트시트)

| 프리픽스 | 기능 | 예시 |
|----------|------|------|
| *(없음)* | 앱·파일 퍼지 검색 + 앱 단축키 | `vscode`, `크롬`, `ㅅㄷ` (초성) |
| `=` | **계산기** — 수식 즉시 계산, Enter로 결과 복사 | `= sqrt(16)`, `= 2^10`, `= sin(30)` |
| `/` | **시스템 명령** — 잠금·절전·재시작·종료 | `/lock`, `/sleep`, `/shutdown` |
| `;` | **텍스트 스니펫** — 키워드로 저장된 텍스트 붙여넣기 | `;addr`, `;sig` |
| `#` | **클립보드 히스토리** — 복사 이력 검색 & 재사용 | `# hello`, `#` |
| `@` | URL 단축키 | `@gh` → GitHub 열기 |
| `~` | 폴더 단축키 | `~dl` → Downloads 폴더 |
| `>` | 명령 실행 / 배치 단축키 | `>git status` |
| `$` | 클립보드 텍스트 변환 (12종) | `$json`, `$b64e`, `$upper`, `$ts` |
| `!` | 워크스페이스 저장·복원 | `!save work`, `!restore work` |

### Alfred 대비 기능 현황

| 기능 | Alfred | AX Commander |
|------|--------|-----------------|
| 앱 퍼지 검색 | ✅ | ✅ |
| 한국어 초성 검색 | ❌ | ✅ |
| 파일 검색 | ✅ | ✅ (exe/lnk/bat/ps1) |
| 계산기 | ✅ | ✅ `=` 프리픽스 |
| 시스템 명령 | ✅ | ✅ `/` 프리픽스 (7가지) |
| 텍스트 스니펫 | ✅ | ✅ `;` 프리픽스 + 변수 치환 |
| 클립보드 히스토리 | ✅ | ✅ `#` 프리픽스 |
| 클립보드 변환 | ❌ | ✅ `$` 프리픽스 (12종) |
| URL 단축키 | ✅ | ✅ `@` 프리픽스 |
| 폴더 단축키 | ✅ | ✅ `~` 프리픽스 |
| 터미널 명령 | ✅ | ✅ `>` 프리픽스 |
| 워크스페이스 관리 | ❌ | ✅ `!` 프리픽스 |
| 플러그인 SDK | ✅ | ✅ (`IActionHandler`) |
| HTTP API 스킬 | ✅ | ✅ (`.skill.json`) |
| 테마 커스터마이징 | ❌ | ✅ (7종 프리셋 + 완전 커스텀) |
| 설정 UI | ✅ | ✅ (7탭 전체 GUI 설정) |

---

## 설치 및 빌드

### 요구 사항

- **OS**: Windows 10 20H2 이상 (Windows 11 권장)
- **.NET**: 8.0 Runtime (Self-contained 빌드 시 불필요)

### 빌드

```bash
# 소스 클론
git clone https://github.com/your/oledic.git
cd "oledic/AX Commander"

# 개발 실행
dotnet run --project src/AxCommander

# Release 단일 파일 빌드 (self-contained)
dotnet publish src/AxCommander -c Release -r win-x64 --self-contained
```

### 데이터 경로

| 용도 | 경로 |
|------|------|
| 설정 파일 | `%APPDATA%\AxCommander\settings.json` |
| 로그 | `%APPDATA%\AxCommander\logs\app-YYYY-MM-DD.log` |
| 스킬 파일 | `%APPDATA%\AxCommander\skills\*.skill.json` |
| 크래시 덤프 | `%APPDATA%\AxCommander\crashes\` |

---

## 사용법

### 키보드 단축키

| 동작 | 단축키 |
|------|--------|
| 런처 열기 / 닫기 | `Alt+Space` |
| 설정 열기 | `Ctrl+,` |
| 다음 항목 선택 | `↓` |
| 이전 항목 선택 | `↑` |
| 실행 | `Enter` |
| 자동완성 (선택 항목 제목 채우기) | `Tab` |
| 닫기 | `Esc` |

### 계산기 예시

```
= 1 + 2 * 3          → 7
= sqrt(144)          → 12
= 2^10               → 1024
= sin(30)            → 0.5     (도 단위)
= log(1000)          → 3
= pi * 5^2           → 78.5398...
= 0xFF + 16          → 271
= round(3.14159, 2)  → 3.14
```

### 스니펫 변수

스니펫 내용에서 아래 변수를 사용할 수 있습니다:

| 변수 | 치환 값 | 예시 |
|------|---------|------|
| `{date}` | 오늘 날짜 | `2026-03-23` |
| `{time}` | 현재 시각 | `14:30:00` |
| `{datetime}` | 날짜+시각 | `2026-03-23 14:30:00` |
| `{year}` | 연도 | `2026` |
| `{month}` | 월 (2자리) | `03` |
| `{day}` | 일 (2자리) | `23` |

---

## 플러그인 개발

### DLL 플러그인

`AxCommander.SDK`를 참조하여 `IActionHandler` 인터페이스를 구현합니다.

```csharp
using AxCommander.SDK;

public class MyHandler : IActionHandler
{
    public string? Prefix => "?";   // 트리거 프리픽스 (null이면 prefix 없는 핸들러)
    public PluginMetadata Metadata => new("MyPlugin", "설명", Version: "1.0");

    public async Task<IEnumerable<LauncherItem>> GetItemsAsync(string query, CancellationToken ct)
    {
        return [ new LauncherItem("제목", "부제목", null, myData, Symbol: "\uE721") ];
    }

    public Task ExecuteAsync(LauncherItem item, CancellationToken ct)
    {
        // item.Data로 전달한 데이터를 꺼내 실행 로직 작성
        return Task.CompletedTask;
    }
}
```

빌드한 DLL 경로를 `settings.json`의 `plugins` 배열에 추가:

```json
{
  "plugins": [
    { "path": "C:\\MyPlugins\\MyPlugin.dll", "enabled": true }
  ]
}
```

### JSON 스킬 (코드 없이 HTTP API 연동)

`%APPDATA%\AxCommander\skills\` 에 `.skill.json` 파일을 놓으면 됩니다.

```json
{
  "id": "github-search",
  "name": "GitHub 검색",
  "prefix": "@gh",
  "credential": { "type": "bearer_token", "credentialKey": "github_token" },
  "request": {
    "method": "GET",
    "url": "https://api.github.com/search/repositories?q={{INPUT}}&per_page=10"
  },
  "response": {
    "resultsPath": "items",
    "titleField": "full_name",
    "subtitleField": "description",
    "actionUrl": "html_url"
  },
  "cache": 30
}
```

---

## 테마

7가지 내장 테마와 완전 커스텀 테마를 지원합니다.

| 테마 | 특징 |
|------|------|
| `system` | Windows 다크/라이트 모드 자동 감지 |
| `dark` | 딥 네이비 다크 (기본) |
| `light` | 클린 화이트 라이트 |
| `oled` | 순수 블랙 (OLED 절전) |
| `nord` | Arctic 컬러 팔레트 |
| `monokai` | Sublime Text 스타일 |
| `catppuccin` | Mocha 따뜻한 파스텔 |
| `sepia` | 황갈색 아날로그 감성 |
| `custom` | 14개 색상 완전 커스터마이징 |

설정 UI(`Ctrl+,` → 테마 탭)에서 클릭 한 번으로 즉시 미리보기 적용.

---

## 변경 이력

### v1.6.1 — 전체 점검 수정

| 분류 | 내용 |
|------|------|
| 빌드 오류 수정 | `using System.IO` 누락, `Key.Enter`/`Key.Return` 중복 switch 케이스, `EnumDisplayMonitors` 람다 타입 혼합, `icon.ico` 다이아몬드 픽셀 보석 아이콘으로 교체, nullable 역참조 경고 |
| 런타임 버그 수정 | JSON 스킬 경로 파싱(`field[0` 형식 오류 방지), 클립보드 서비스 스레드 안전성, 디바운스 타이머 원자적 교체, 설정 백업 실패 로깅 |
| 보안 수정 | JSON 스킬 `ActionUrl` 실행 전 `http`/`https` 스킴 검증 추가 |
| 데드 코드 제거 | `SystemCommandHandler` no-op `timer`/`alarm` 항목 제거 |

자세한 내용은 [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md)의 "v1.6 3차 전체 점검 수정" 섹션을 참고하세요.

---

## 라이선스

MIT License
