chore: 저장소 구조 정리 및 문서화, 첫 커밋

- src/dist 산출물 분리 원칙 정리(.gitignore, .gitattributes)
- 루트 및 주요 폴더(config/scripts/prompts/tests/src, 런타임 폴더 5종)에
  안내용 README.md 추가
- CHANGELOG.md, LICENSE, docs/ops/05-release-and-versioning.md 추가
- docs/README.md 문서 지도 갱신
This commit is contained in:
Yun Chan 2026-09-04 09:25:44 +09:00
commit 56a6e2da93
159 changed files with 145825 additions and 0 deletions

101
scripts/make_shortcuts.ps1 Normal file
View file

@ -0,0 +1,101 @@
#Requires -Version 5.1
<#
.SYNOPSIS
"DMF 설정.lnk" / "지금 실행.lnk" 프로젝트 루트와 바탕화면에 만든다.
.DESCRIPTION
대상은 반드시 pythonw.exe . python.exe .cmd 대상으로 하면
더블클릭할 때마다 검은 콘솔 창이 번쩍인다(PE 서브시스템 = WINDOWS_CUI).
관리자 권한은 필요하지 않다. 멱등하다 번을 다시 실행해도
기존 바로가기를 덮어쓸 중복 파일을 만들지 않는다.
.PARAMETER ProjectRoot
프로젝트 루트 경로. bootstrap.cmd 자신의 위치를 넘겨준다.
.EXAMPLE
powershell -ExecutionPolicy Bypass -File .\scripts\make_shortcuts.ps1 -ProjectRoot "D:\workspace\DMF_Crawler"
#>
[CmdletBinding()]
param(
[Parameter(Mandatory)]
[string]$ProjectRoot
)
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
function Write-Step { param([string]$Message) Write-Host "[make_shortcuts] $Message" }
function Write-Warn { param([string]$Message) Write-Host "[make_shortcuts] ! $Message" -ForegroundColor Yellow }
try {
$ProjectRoot = (Resolve-Path -LiteralPath $ProjectRoot).Path
} catch {
throw "프로젝트 루트를 찾을 수 없습니다: $ProjectRoot"
}
$pythonw = Join-Path $ProjectRoot '.venv\Scripts\pythonw.exe'
if (-not (Test-Path -LiteralPath $pythonw)) {
throw "실행 환경을 찾을 수 없습니다: $pythonw`n → bootstrap.cmd 를 먼저 실행하세요."
}
# 아이콘: 있으면 전용 아이콘, 없으면 시스템 폴백(진단 문서 아이콘)을 쓴다.
$iconFile = Join-Path $ProjectRoot 'assets\dmf.ico'
if (-not (Test-Path -LiteralPath $iconFile)) {
$iconFile = "$env:SystemRoot\System32\imageres.dll,109"
}
$desktop = [System.Environment]::GetFolderPath('Desktop')
$targets = @($ProjectRoot, $desktop) |
Where-Object { $_ -and (Test-Path -LiteralPath $_) } |
Select-Object -Unique
if ($targets.Count -eq 0) {
throw '바로가기를 놓을 수 있는 폴더가 없습니다(프로젝트 루트도, 바탕화면도 접근 불가).'
}
# 지금 실행.lnk 는 "검사 → CRITICAL 통과면 즉시 실행" 모드로 들어간다(onboard --mode inspect --run-now).
$specs = @(
@{ Name = 'DMF 설정.lnk'
Args = '-m dmf_crawler onboard --mode setup'
Desc = 'DMF 크롤러 설정 및 상태 확인' },
@{ Name = '지금 실행.lnk'
Args = '-m dmf_crawler onboard --mode inspect --run-now'
Desc = 'DMF 자료를 지금 받아 리포트를 만듭니다' }
)
$shell = New-Object -ComObject WScript.Shell
$created = 0
$failed = 0
try {
foreach ($dir in $targets) {
foreach ($s in $specs) {
$path = Join-Path $dir $s.Name
try {
$lnk = $shell.CreateShortcut($path)
$lnk.TargetPath = $pythonw
$lnk.Arguments = $s.Args
$lnk.WorkingDirectory = $ProjectRoot
$lnk.IconLocation = $iconFile
$lnk.Description = $s.Desc
$lnk.WindowStyle = 1 # SW_SHOWNORMAL — 호스트가 GUI 라 콘솔은 뜨지 않는다
$lnk.Save()
Write-Step "바로가기 생성: $path"
$created++
} catch {
Write-Warn "바로가기 생성 실패: $path ($($_.Exception.Message))"
$failed++
} finally {
if ($lnk) { [void][System.Runtime.InteropServices.Marshal]::ReleaseComObject($lnk) }
}
}
}
} finally {
[void][System.Runtime.InteropServices.Marshal]::ReleaseComObject($shell)
}
Write-Step "완료: $created 개 생성, $failed 개 실패"
# 바탕화면 접근 실패 등으로 전부 실패했을 때만 비정상 종료로 알린다.
# 부분 성공(예: 프로젝트 루트만 성공)은 실사용에 지장이 없으므로 0으로 끝낸다.
if ($created -eq 0) { exit 1 }
exit 0